10

次の 2 つの文:

hello there
bye!

文_単語テーブルでは、次のように表されます。

WORD_ID  SENTENCE_ID    WORD    WORD_NUMBER
10       1              hello   1
11       1              there   2
12       2              bye!    1

結果が得られる外部結合クエリを実行したい:

WORD1      WORD2
hello      there
bye!       NULL

文の途中から開始したい場合があるため、word2 が word_number = 2 であると想定できないことに注意してください。 my_start_number = 2 を選択すると、クエリは次のようになります。

WORD1   WORD2
there   NULL

私は試した:

(my_start_number = 1)

select  s1.word word1, s2.word word2
from sentence_words s1
left join sentence_words s2
on s1.sentence_id = s2.sentence_id
where s1.word_number = my_start_number
 and (s2.word_number = s1.word_number +1 or s2.word_number is null);

文に2つの単語がある場合にのみ結果が得られます。どうすればいいのかわからないのですが、それほど複雑ではありません。

4

2 に答える 2

12

word_number + 1要件を に移動しますLEFT JOIN

SELECT
  s1.word word1, s2.word word2
FROM
  sentence_words s1
LEFT JOIN
  sentence_words s2
    ON  s2.sentence_id = s1.sentence_id
    AND s2.word_number = s1.word_number + 1
WHERE
  s1.word_number = my_start_number

ネクロ編集:

上記はLEFT JOINの使用を修正しましたが、結合をまったく使用しないことをお勧めします...

SELECT
  sentence_id,
  MAX(CASE WHEN pos = 0 THEN word END)   AS word1,
  MAX(CASE WHEN pos = 1 THEN word END)   AS word2
FROM
(
  SELECT
    sentence_id,
    word_number - MY_START_NUMBER   AS pos,
    word
  FROM
    sentence_words
)
  AS offset_sentence_words
WHERE
  pos IN (0, 1)
GROUP BY
  sentence_id
于 2012-04-26T14:01:10.910 に答える
1

Demsの答えは絶対に正しいものです。元のソリューションが機能しない理由を説明するために、この回答を書くことにしました。これは、左外部結合の次の結果セットをフィルター処理しようとしているからです (すべての列を表示し、一部の名前は短縮されています)。

s1.WORD_ID s1.SENT_ID s1.WORD  s1.WORD_NUM s2.WORD_ID s2.SENT_ID s2.WORD  s2.WORD_NUM
10         1          hello    1           10         1          hello    1
10         1          hello    1           11         1          there    2
11         1          there    2           10         1          hello    1
11         1          there    2           11         1          there    2
12         2          bye!     1           12         2          bye!     1

ここで、where 句を見てください。

where s1.word_number = my_start_number  
 and (s2.word_number = s1.word_number +1 or s2.word_number is null);  

...そして、それが機能しない理由は比較的簡単にわかるはずです。たとえば、s2.word_number決して ではありませんNULL

于 2012-04-26T14:12:25.210 に答える