web-dev-qa-db-ja.com

(WHERE)条件で選択された行から前の行と次の行を取得する

たとえば、私はこの声明を持っています:

my name is Joseph and my father's name is Brian

このステートメントは、次の表のようにWordによって分割されます。

------------------------------
|      ID      |   Word      |
------------------------------
|       1      |   my        |
|       2      |   name      |
|       3      |   is        |
|       4      |   Joseph    |
|       5      |   and       |
|       6      |   my        |
|       7      |   father's  |
|       8      |   name      |
|       9      |   is        |
|       10     |   Brian     |
------------------------------

各単語の前後の単語を取得したい

たとえば、「名前」の前後の単語を取得したい:

--------------------------
|    my    |  name  |  is |
--------------------------
| father's |  name  |  is |
--------------------------

この結果を取得するにはどうすればよいですか?

20
mahdi yousefi

dBMSを指定しなかったため、次はANSI SQLです。

select prev_Word, Word, next_Word
from (
    select id, 
           lag(Word) over (order by id) as prev_Word,
           Word,
           lead(Word) over (order by id) as next_Word
    from words
) as t
where Word = 'name';

SQLFiddle: http://sqlfiddle.com/#!12/7639e/1

39

誰も簡単な答えを出さなかったのはなぜですか?

SELECT LAG(Word) OVER ( ORDER BY ID ) AS PreviousWord ,
       Word ,
       LEAD(Word) OVER ( ORDER BY ID ) AS NextWord
FROM   words;
7
Nick P

サブクエリなし:

SELECT a.Word 
FROM my_table AS a
JOIN my_table AS b 
ON b.Word = 'name' AND abs(a.id - b.id) <= 1
ORDER BY a.id
6
Will

Joinを使用して、SQL Server 2005 plusの期待される結果を取得します。

    create table words (id integer, Word varchar(20));

    insert into words
    values
    (1 ,'my'),
    (2 ,'name'),
    (3 ,'is'),
    (4 ,'joseph'),
    (5 ,'and'),
    (6 ,'my'),
    (7 ,'father'),
    (8 ,'name'),
    (9 ,'is'),
    (10,'brian');

SELECT A.Id ,  C.Word AS PrevName , 
               A.Word AS CurName , 
               B.Word AS NxtName 
FROM words AS A
LEFT JOIN words AS B ON A.Id = B.Id - 1
LEFT JOIN words AS C ON A.Id = C.Id + 1
WHERE A.Word = 'name'

結果:

enter image description here

フィドラーデモ

3
Saravana Kumar

これを試して

SELECT *
FROM   tablename a
WHERE  ID IN(SELECT ID - 1
             FROM   tablename 
             WHERE  Word = 'name') -- will fetch previous rows of Word `name` 
        OR ID IN(SELECT ID + 1
                 FROM   tablename 
                 WHERE  Word = 'name') -- will fetch next rows of Word `name`
        OR Word = 'name' -- to fetch the rows where Word = `name`
2

選択を高速にしたい場合は、別のアプローチを使用します。少し準備作業が必要です。

  • 必要な単語を含む新しい列(「フレーズ」など)をデータベースに作成します。 (つまり、前、現在、および次)。

  • 挿入時に新しいWordを前の行のフレーズに追加し、前の行のWordを新しい行のWordの前に追加してフレーズを埋めるトリガーを記述します。

  • 個々の単語が変更される可能性がある場合は、更新時にトリガーを使用してフレーズの同期を保つ必要があります。

次に、フレーズを選択します。速度は大幅に向上しますが、追加のストレージと低速の挿入、および保守性の犠牲が伴います。明らかに、既存のレコードのフレーズ列を更新する必要がありますが、他の回答ではそれを行うSQLがあります。

1
mlinth