Проблема с левым соединением - PullRequest
0 голосов
/ 27 декабря 2011

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

У меня есть две таблицы в системе продаж / оплаты, однакоторый содержит различные способы оплаты и связанные детали, а другой содержит продажи, включая идентификаторы, итоги и способ оплаты.

В конце периода я хочу подвести итоги по всем различным методам,или NULL или 0, если его не было.

У меня есть запрос:

SELECT m.method_id, m.description, SUM(s.total) as total 
FROM payment_method m 
         LEFT JOIN sale s ON s.payment_method = m.method_id 
 WHERE m.for_stock_keeping = 0 AND 
 (s.shift_id = ? OR s.shift_id IS NULL) 
 GROUP BY m.method_id;

Он работает нормально, пока мы не начнем другую смену с новым идентификатором, а затем любые способы оплаты, которыеиспользовались в предыдущую смену, больше не отображаются, если продажи для этого метода не происходят.То есть: если я совершу 10 продаж за наличные в эту смену, а затем начну новую смену, наличные больше не будут отображаться со значением NULL, а появятся только после того, как была совершена продажа за наличные, и для нее есть значение.Это не то поведение, которое мне нужно.

Любая помощь будет очень признательна!

Спасибо, Райан.

Ответы [ 3 ]

1 голос
/ 27 декабря 2011

Условие s.shift_id в предложении WHERE применяется после внешнего соединения;вам нужно применить его раньше.

У вас есть два варианта (как минимум):

SELECT m.method_id, m.description, SUM(s.total) as total 
  FROM payment_method m 
  LEFT JOIN sale s ON s.payment_method = m.method_id AND 
                       (s.shift_id = ? OR s.shift_id IS NULL)
 WHERE m.for_stock_keeping = 0 
 GROUP BY m.method_id, m.description;

и:

SELECT m.method_id, m.description, SUM(s.total) as total 
  FROM payment_method m 
  LEFT JOIN (SELECT * FROM Sale AS a WHERE a.shift_id = ? OR a.shift_id IS NULL) AS s
    ON s.payment_method = m.method_id 
 WHERE m.for_stock_keeping = 0 
 GROUP BY m.method_id, m.description;
1 голос
/ 27 декабря 2011

Любой критерий в вашем предложении WHERE, который относится к таблице справа от LEFT JOIN, будет означать, что запрос возвращает 0 строк, когда ничто не соответствует JOIN (поскольку эти поля не существуют)

поэтому, когда вы говорите

ГДЕ

(s.shift_id = ? OR s.shift_id IS NULL) 

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

Итак, просто переместите чек в JOIN, и все будет в порядке.

SELECT m.method_id, m.description, SUM(s.total) as total 
FROM payment_method m 
         LEFT JOIN sale s ON s.payment_method = m.method_id AND (s.shift_id = ? OR s.shift_id IS NULL)
 WHERE m.for_stock_keeping = 0  
 GROUP BY m.method_id;
0 голосов
/ 27 декабря 2011

Запрос выглядит нормально, но, возможно, ваша СУБД суетится, поскольку m.method_id не является ни агрегатной функцией, ни предложением group by. Попробуйте это:

SELECT m.method_id, m.description, SUM(s.total) as total
FROM payment_method m LEFT JOIN sale s ON s.payment_method = m.method_id
WHERE m.for_stock_keeping = 0 AND (s.shift_id = ? OR s.shift_id IS NULL)
GROUP BY m.method_id, m.description;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...