Чем больше объединений, тем меньше результатов в запросе PSQL

У меня есть следующая таблица PSQL. На самом деле он имеет примерно 2 миллиарда строк.

 id  word      lemma     pos              textid  country_genre     
 1  Stuffing   stuff      vvg             190568  AN         
 2  her        her        appge           190568  AN         
 3  key        key        nn1             190568  AN         
 4  into       into       ii              190568  AN         
 5  the        the        at              190568  AN         
 6  lock       lock       nn1             190568  AN         
 7  she        she        appge           190568  AN         
 8  pushed     push       vvd             190568  AN         
 9  her        her        appge           190568  AN         
10  way        way        nn1             190568  AN         
11  into       into       ii              190568  AN         
12  the        the        appge           190568  AN         
13  house      house      nn1             190568  AN         
14  .                     .               190568  AN         
15  She        she        appge           190568  AN         
16  had        have       vhd             190568  AN         
17  also       also       rr              190568  AN         
18  cajoled    cajole     vvd             190568  AN         
19  her        her        appge           190568  AN         
20  way        way        nn1             190568  AN         
21  into       into       ii              190568  AN         
22  the        the        at              190568  AN         
23  home       home       nn1             190568  AN         
24  .                     .               190568  AN         
..  ...        ...        ..              ...     ..

Я хотел бы создать следующую таблицу, которая показывает все "way"-идиомы со словами рядом и некоторые данные из столбцов "country_genre", "lemma" и "pos".

country_genre word   word       word       lemma      pos        word       word     word       word       word       lemma      pos        word       word       
AN         lock   she        pushed     push       vvd        her        way      into       the        house      house      nn1        .          she
AN         had    also       cajoled    cajole     vvd        her        way      into       the        home       home       nn1        .          A          
AN         tried  to         force      force      vvi        her        way      into       the        palace     palace     nn1        ,          officials  

Я использую следующий код (спасибо Bohemian: /questions/22671930/uzh-bolno-medlennyij-zapros-postgres-s-ispolzovaniem-where-na-mnogih-sosednih-strokah/22671940#22671940!):

copy(

 SELECT
   c1.id, c1.country_genre, c1.textid, c1.wordid, c1.word,  c2.word, c3.word,  c4.word, c4.lemma, c4.pos, c5.word, c6.word, c7.word, c8.word, c9.word, c9.lemma, c9.pos, c10.word, c11.word

 FROM

 orderedflatcorpus AS c1
 JOIN orderedflatcorpus AS c2 ON c1.id + 1 = c2.id
 JOIN orderedflatcorpus AS c3 ON c1.id + 2 = c3.id 
 JOIN orderedflatcorpus AS c4 ON c1.id + 3 = c4.id
 JOIN orderedflatcorpus AS c5 ON c1.id + 4 = c5.id
 JOIN orderedflatcorpus AS c6 ON c1.id + 5 = c6.id
 JOIN orderedflatcorpus AS c7 ON c1.id + 6 = c7.id
 JOIN orderedflatcorpus AS c8 ON c1.id + 7 = c8.id
 JOIN orderedflatcorpus AS c9 ON c1.id + 8 = c9.id
 JOIN orderedflatcorpus AS c10 ON c1.id + 9 = c10.id
 JOIN orderedflatcorpus AS c11 ON c1.id + 10 = c11.id

 WHERE

 c4.pos LIKE 'vv%'
 AND c5.pos = 'appge'
 AND c6.word = 'way'
 AND c7.pos LIKE 'i%'
 AND c8.word = 'the'
 AND c9.pos LIKE 'n%'
 )

 TO

 '/home/postgres/Results/OUTPUT.csv'
 DELIMITER E'\t'
 csv header;

Этот запрос возвращает 18706 соответствующих конструкций.

Однако, если я использую следующий код, который извлекает больше контекста (21 вместо 11 слов), но в остальном равен предыдущему, случается что-то тревожное: я получаю только 18555 соответствующих конструкций.

 copy(
 SELECT c1.id, c1.country_genre, c1.textid, c1.wordid, c1.word, c1.pos, c2.word, c2.pos, c3.word, c3.pos, c4.word, c4.pos, c5.word, c5.pos, c6.word, c6.pos, 
 c7.word, c7.pos, c8.word, c8.pos, c8.lemma, c9.word, c9.pos, c10.word, c10.pos, c11.word, c11.pos, c12.word, c12.pos, c13.word, c13.pos, c13.lemma, c14.word, 
 c14.pos, c15.word, c15.pos, c16.word, c16.pos, c17.word, c17.pos, c18.word, c18.pos, c19.word, c19.pos, c20.word, c20.pos, c21.word, c21.pos 

 FROM 

 orderedflatcorpus AS c1 
 JOIN orderedflatcorpus AS c2 ON c1.id + 1 = c2.id 
 JOIN orderedflatcorpus AS c3 ON c1.id + 2 = c3.id 
 JOIN orderedflatcorpus AS c4 ON c1.id + 3 = c4.id 
 JOIN orderedflatcorpus AS c5 ON c1.id + 4 = c5.id 
 JOIN orderedflatcorpus AS c6 ON c1.id + 5 = c6.id 
 JOIN orderedflatcorpus AS c7 ON c1.id + 6 = c7.id 
 JOIN orderedflatcorpus AS c8 ON c1.id + 7 = c8.id 
 JOIN orderedflatcorpus AS c9 ON c1.id + 8 = c9.id 
 JOIN orderedflatcorpus AS c10 ON c1.id + 9 = c10.id 
 JOIN orderedflatcorpus AS c11 ON c1.id + 10 = c11.id 
 JOIN orderedflatcorpus AS c12 ON c1.id + 11 = c12.id 
 JOIN orderedflatcorpus AS c13 ON c1.id + 12 = c13.id 
 JOIN orderedflatcorpus AS c14 ON c1.id + 13 = c14.id 
 JOIN orderedflatcorpus AS c15 ON c1.id + 14 = c15.id 
 JOIN orderedflatcorpus AS c16 ON c1.id + 15 = c16.id 
 JOIN orderedflatcorpus AS c17 ON c1.id + 16 = c17.id 
 JOIN orderedflatcorpus AS c18 ON c1.id + 17 = c18.id 
 JOIN orderedflatcorpus AS c19 ON c1.id + 18 = c19.id 
 JOIN orderedflatcorpus AS c20 ON c1.id + 19 = c20.id 
 JOIN orderedflatcorpus AS c21 ON c1.id + 20 = c21.id 

 WHERE 

 c8.pos LIKE 'vv%' 
 AND c9.pos = 'appge' 
 AND c10.word = 'way' 
 AND c11.pos LIKE 'i%' 
 AND c12.word = 'the' 
 AND c13.pos LIKE 'n%' 
 ) 
 TO '/home/postgres/Results/OUTPUT.csv' DELIMITER E'\t' csv header;

Я посмотрел на строки, которые отсутствуют во втором запросе, но я не могу обнаружить какой-либо шаблон в том, что было пропущено.

У кого-нибудь есть идея, что здесь может происходить? Спасибо!

2 ответа

Пирхо ответ правильный - насколько это возможно. Однако простая замена соединений на внешние соединения может не решить вашу проблему.

Во-первых, where условия для двух запросов различны, поэтому у меня нет оснований предполагать, что они будут возвращать один и тот же набор результатов.

Второй запрос ищет ровно 21 слово подряд - не 19 слов, а не 13 слов. Поэтому, если шаблон находится в конце документа, он не будет найден.

Исходя из ваших условий, есть 13 слов, которые должны появиться в строке (чтобы перейти к счету "13" для ваших условий. Тогда, я предполагаю, необязательные 7 строк. Для этого требуется смесь внутренних и внешних объединений:

FROM orderedflatcorpus c1 JOIN
     orderedflatcorpus c2
     ON c1.id + 1 = c2.id JOIN
     orderedflatcorpus c3
     ON c1.id + 2 = c3.id JOIN
     orderedflatcorpus c4
     ON c1.id + 3 = c4.id JOIN
     orderedflatcorpus c5
     ON c1.id + 4 = c5.id JOIN
     orderedflatcorpus c6
     ON c1.id + 5 = c6.id JOIN
     orderedflatcorpus c7
     ON c1.id + 6 = c7.id JOIN
     orderedflatcorpus c8
     ON c1.id + 7 = c8.id JOIN
     orderedflatcorpus c9
     ON c1.id + 8 = c9.id JOIN
     orderedflatcorpus c10
     ON c1.id + 9 = c10.id JOIN
     orderedflatcorpus c11
     ON c1.id + 10 = c11.id JOIN
     orderedflatcorpus c12
     ON c1.id + 11 = c12.id JOIN
     orderedflatcorpus c13
     ON c1.id + 12 = c13.id 
     orderedflatcorpus c14
     ON c1.id + 13 = c14.id LEFT JOIN
     orderedflatcorpus c15
     ON c1.id + 14 = c15.id LEFT JOIN
     orderedflatcorpus c16
     ON c1.id + 15 = c16.id LEFT JOIN
     orderedflatcorpus c17
     ON c1.id + 16 = c17.id LEFT JOIN
     orderedflatcorpus c18
     ON c1.id + 17 = c18.id LEFT JOIN
     orderedflatcorpus c19
     ON c1.id + 18 = c19.id LEFT JOIN
     orderedflatcorpus c20
     ON c1.id + 19 = c20.id LEFT JOIN
     orderedflatcorpus c21
     ON c1.id + 20 = c21.id 
WHERE c8.pos LIKE 'vv%' AND
      c9.pos = 'appge' AND
      c10.word = 'way' AND
      c11.pos LIKE 'i%' AND
      c12.word = 'the' AND
      c13.pos LIKE 'n%' ;

Далее: я подозреваю, что country и / или textid должен быть частью join условия.

В PostgresJOIN эквивалентно INNER JOIN, Смотрите это, например.

Другими словами, ваш запрос требует совпадения со всеми ON предикаты, чтобы иметь результат. Добавление больше JOINS увеличивается также ON предикаты, которые не могли соответствовать, таким образом уменьшая количество результатов.

Попробуй поменять JOIN в LEFT JOIN (ака LEFT OUTER JOIN), чтобы увидеть, если вы получите больше результатов.

Не видя данных вашего примера и примера того, чего не хватает в наборе результатов, трудно сказать, в чем еще может быть проблема.

Другие вопросы по тегам