MySQL Left Join не дает ожидаемых результатов

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

У меня есть две таблицы с продажами подарочных карт. Я должен убедиться, что суммы совпадают. Я ищу помощь в написании запроса, который будет возвращать все из таблицы A, даже если в таблице B нет соответствующей записи.

ТАБЛИЦА А

| id | business_date | am_pm | gift_cards_sold | 
================================================
 103 | 2011-10-06    | PM    | 175.03
 104 | 2011-10-06    | PM    | 135.03
 105 | 2011-10-06    | PM    | 250.74
 106 | 2011-10-06    | PM    | 180.44
 107 | 2011-10-06    | PM    | 150.10
 108 | 2011-10-06    | PM    | 130.00

ТАБЛИЦА Б

| id | business_date | am_pm | gift_cards_sold | 
================================================
 103 | 2011-10-06    | PM    | 100.03
 105 | 2011-10-06    | PM    | 250.74
 106 | 2011-10-06    | PM    | 180.44
 107 | 2011-10-06    | PM    | 150.10

Вот мой запрос (очевидно, что-то не так с ним)

SELECT A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
FROM A
LEFT JOIN B
USING (id)
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
AND B.business_date = '2011-10-06'
GROUP BY A.id
ORDER BY A.id ASC

Вот результат:

| id | A_SOLD | B_SOLD | 
========================
 103 | 175.03 | 100.03
 105 | 250.74 | 250.74
 106 | 180.44 | 180.44
 107 | 150.10 | 150.10

Как вы можете видеть, есть разница с идентификатором 103. Однако мне нужно, чтобы результат показывал каждый идентификатор независимо от того, есть совпадение или нет. Результирующий набор - это то, что я ожидаю от использования Inner Join.

4 ответа

Решение

Просто переместите B.business_date = '2011-10-06' состояние из WHERE к ON пункт. Когда у вас есть LEFT присоединиться WHERE условие о столбцах второй таблицы (кроме IS (NOT) NULL те) фактически отменяет LEFT JOINзатем он действует как INNER JOIN,

SELECT A.id AS ID
     , A.gift_cards_sold AS A_SOLD
     , B.gift_cards_sold AS B_SOLD
FROM A
  LEFT JOIN B
    ON  B.id = A.id
    AND B.business_date = '2011-10-06'
WHERE A.am_pm = 'PM'
  AND A.business_date = '2011-10-06'
ORDER BY A.id

Вы должны использовать что-то вроде этого:

SELECT A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
FROM A
LEFT JOIN B
USING (id)
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
AND (B.business_date = '2011-10-06' or B.business_date is null)
GROUP BY A.id
ORDER BY A.id ASC

Я не уверен, почему вы использовали предложение "group by" - здесь это не нужно, а в большинстве других баз данных будет синтаксическая ошибка.

Я предполагаю, что вам нужно только сопоставить строки по идентификатору.

Это должно работать:

select A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
 from A left join b on b.id = a.id
where A.business_date = '2011-10-06'  
  and A.am_pm = 'PM'
order by a.id

Проблема с условием where для B.business_date, оно также должно разрешать ноль

SELECT A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
FROM A LEFT JOIN B ON A.id = B.id
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
AND (B.business_date = '2011-10-06' OR B.business_date is null )
ORDER BY A.id ASC
Другие вопросы по тегам