LEFT JOIN не работает должным образом при получении данных из 2 таблиц - PullRequest
2 голосов
/ 30 октября 2011

У меня есть 2 таблицы с именами subscriptions и tags.Раз в месяц мне нужно будет создавать теги для каждого заказа.

Я должен перечислять подписки без тега на данный месяц (2011-10-01 или 2011-09-01 и т. Д.).Этот запрос возвращает 0 записей:

   SELECT s.id, s.active, s.status 
     FROM asw_subscriptions as s 
LEFT JOIN asw_tags as t ON s.id = t.subscription_id 
    WHERE t.subscription_id IS NULL 
      AND t.deliveryDate = '2011-10-01' 
      AND s.status = '2' 
      AND s.active = '1' 
 ORDER BY s.id DESC 
    LIMIT 0, 25

Структура таблицы


подписка = id (int / auto), active (enum: 0,1),статус (перечисление: 0,1)

теги = идентификатор (int / auto), дата доставки (дата), номер тега

Ответы [ 3 ]

4 голосов
/ 30 октября 2011

Проблема в клаусуле

t.deliveryDate = '2011-10-01' AND

У вас нет записи слева, потому что условие «IS NULL» удаляет записи, оставленные слева. Таким образом, указанное выше условие исключит все объединяемые продукты, потому что никогда не будет истинным (в t.deliveryDate всегда будет null.

Попробуйте что-то вроде этого:

SELECT s.id, s.active, s.status 
     FROM asw_subscriptions as s 
WHERE s.status = '2' 
      AND s.active = '1' 
      AND NOT EXISTS (
         SELECT 1
         FROM asw_tags as t
         WHERE s.id = t.subscription_id
         AND t.deliveryDate = '2011-10-01'          
      )
 ORDER BY s.id DESC 
    LIMIT 0, 25
2 голосов
/ 30 октября 2011

Проблема в том, что вы проверяете дату тега в том же запросе, который проверяет наличие тега.

Попробуйте это:

SELECT s.id, s.active, s.status 
FROM
    asw_subscriptions as s
    LEFT JOIN (
        SELECT subscription_id
        FROM asw_tags
        WHERE deliveryDate = '2011-10-01'
    ) as t ON s.id = t.subscription_id 
WHERE 
    t.subscription_id IS NULL
    AND s.status = '2'
    AND s.active = '1' 
ORDER BY s.id DESC
LIMIT 0, 25
1 голос
/ 30 октября 2011

Просто поймите, что указание условия в WHERE - вы реализуете INNER JOIN логику, это не то, что вы ожидали. Поэтому поместите весь раздел WHERE под ON OUTER JOIN:

 ... ON s.id = t.subscription_id 
 AND t.subscription_id IS NULL AND 
 t.deliveryDate = '2011-10-01' AND 
 s.status = '2' AND 
 s.active = '1' 
...