たとえば、私はこの声明を持っています:
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 |
--------------------------
この結果を取得するにはどうすればよいですか?
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
誰も簡単な答えを出さなかったのはなぜですか?
SELECT LAG(Word) OVER ( ORDER BY ID ) AS PreviousWord ,
Word ,
LEAD(Word) OVER ( ORDER BY ID ) AS NextWord
FROM words;
サブクエリなし:
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
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'
結果:
これを試して
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`
選択を高速にしたい場合は、別のアプローチを使用します。少し準備作業が必要です。
必要な単語を含む新しい列(「フレーズ」など)をデータベースに作成します。 (つまり、前、現在、および次)。
挿入時に新しいWordを前の行のフレーズに追加し、前の行のWordを新しい行のWordの前に追加してフレーズを埋めるトリガーを記述します。
個々の単語が変更される可能性がある場合は、更新時にトリガーを使用してフレーズの同期を保つ必要があります。
次に、フレーズを選択します。速度は大幅に向上しますが、追加のストレージと低速の挿入、および保守性の犠牲が伴います。明らかに、既存のレコードのフレーズ列を更新する必要がありますが、他の回答ではそれを行うSQLがあります。