2012-04-26 16 views
8

due frasi seguenti:SQL lasciato self-join con WHERE dipendenze clausola tra le due copie della tabella

hello there 
bye! 

sono rappresentati nel sentence_words tavolo da:

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

che voglio fare una query outer join che mi dà i risultati:

WORD1  WORD2 
hello  there 
bye!  NULL 

Nota che potrei voler iniziare nel mezzo o f la frase in modo da non può supporre che parola2 ha word_number = 2. Se scelgo my_start_number = 2 allora la query deve darmi:

WORD1 WORD2 
there NULL 

ho provato:

(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); 

Che solo mi dà un risultato se ci sono due parole nella frase. Non sono sicuro di cosa fare, non è molto complicato.

+0

Cosa stanno usando mssql, mysql, oracel? – Arion

+0

Stai cercando di ricreare la frase o sei interessato solo a restituire coppie di parole? –

risposta

10

Spostare il requisito word_number + 1 nello 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 
+0

Brillante - Funziona perfettamente. – user984003

1

La risposta di Dems è assolutamente corretta. Ho deciso di scrivere questa risposta per spiegare il motivo per cui la tua soluzione originale non funziona. Questo perché si sta cercando di filtrare il seguente set di risultati del outter LEFT JOIN (che mostra tutte le colonne, con alcuni nomi abbreviati per adattarsi):

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 

Ora, date un'occhiata al tuo clausola WHERE:

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

... e dovrebbe essere relativamente facile capire perché non funziona. Ad esempio, s2.word_number non è mai NULL.