2012-05-03 3 views
1

В настоящее время я использую следующий запрос для выполнения поиска по нескольким таблицам через INNER JOIN.Несколько внутренних соединений с различными условиями где-то

SELECT title, m2.txt1 AS teaser, inputdat, db_file.* 
     FROM db_item 
      INNER JOIN db_itemv AS m1 USING(id_item) 
      INNER JOIN db_itemf USING(id_item) 
      INNER JOIN db_itemd USING(id_item) 
      INNER JOIN db_itemv AS m2 USING(id_item) 
     WHERE type=15 AND m1.fldnr='12' 
AND m1.indik='b' AND m1.txt1s='en' 
AND visibility=0 AND inputdat>'2005-11-02' AND m2.fldnr='123' 
     GROUP BY title 
     ORDER BY inputdat DESC 
     LIMIT 0,100 

Столбцы db_itemv (m1, m2) названы:

ID id_item fldnr indik txt1 

Один id_item может существовать несколько строк.

Моя проблема в том, что m2.fldnr = '123' не всегда существует, и поэтому он выкидывает всю строку. Но я хочу сохранить строку и оставить столбец пустым, если он не существует в строке. Как я могу решить проблему?

+1

использовать 'левое внешнее join' –

ответ

1

Я думаю, что есть несколько вопросов здесь, так что терпите меня в то время как я иду через них :)

Я согласен с @Jeurgen, что вам нужно использовать LEFT JOIN вместо INNER JOIN, который позволит Вам получить все строки, которые вы ищете, включая те, у которых нет записи в m2.

Однако, как ваш, где положение конкретно говорится только дать мне, что данные, которые действительно имеет m2.fldnr значение, равное «123», то это правильно для вас, чтобы не иметь ни одной строки, не имеющие соответствия m2 строки, так как они не может соответствовать вашим критериям.

Я думаю, что вы пытаетесь извлечь все данные из первых четырех таблиц, а затем только данные в таблице m2, которая содержит «123», если это так, то вам необходимо переместить ваш фильтр m2.fldnr , и обрабатывать эти недостающие строки ...

Моя версия вашего запроса выглядит так: это не было протестировано, так как у меня нет выборочных данных с вашей структурой, но попробуйте и измените их. если нужно;

SELECT title, m2.txt1 AS teaser, inputdat, db_file.* 
FROM db_item 
    INNER JOIN db_itemv AS m1 USING(id_item) 
    INNER JOIN db_itemf USING(id_item) 
    INNER JOIN db_itemd USING(id_item) 
    LEFT JOIN db_itemv AS m2 
     ON db_item.id_item = m2.id_item 
     AND (m2.fldnr = '123' OR m2.fldnr IS NULL) 
WHERE type=15 
    AND m1.fldnr = '12' 
    AND m1.indik = 'b' 
    AND m1.txt1s = 'en' 
    AND visibility = 0 
    AND inputdat > '2005-11-02' 
GROUP BY title 
ORDER BY inputdat DESC 

Надежда, что помогает :)

+0

Работает как очарование! Большое спасибо за аккуратное объяснение и запрос :) – blacktea

2

Заменить все inner join с left outer join

+0

, кажется, не решить эту проблему для меня. Когда я выполняю весь запрос без последнего соединения и, следовательно, последнее условие WHERE, результат будет совсем другим. У вас есть другая идея? – blacktea

0

Я думаю, вы должны использовать LEFT JOIN вместо INNER JOIN db_itemv AS m2 , который должен вернуть все другие данные, даже если db_itemv возвращает NULL.