2015-03-27 3 views
0
SELECT i.id invn_id, IF(ss.serial_id IS NOT NULL, ss.serial_id, NULL) serial_number, 
     IF(ss.serial_id IS NOT NULL, 1.000000, -(i.qty)) qty, 
     'auto' flag, i.sid site_id, i.prod_id, i.fifo_total_amount, i.trans_date 
FROM inventories i 
INNER JOIN prod p ON p.id = i.prod_id 
LEFT JOIN sale_products sp ON sp.inventory_id = i.id 
LEFT JOIN sale_serial ss ON ss.prod_id = i.prod_id AND ss.sale_id = sp.sale_id 
WHERE i.qty < 0 
     AND ('2015-03-25 00:00:00' IS NULL OR i.trans_date >= '2015-03-25 00:00:00') 
     AND ('2015-03-27 08:27:36' IS NULL OR i.trans_date <= '2015-03-27 08:27:36') 
     AND p.name NOT IN ('Starting Balance' , 'Opening Balance', 'Equity') 
     AND i.prod_id = 7655 AND (0 = 0 OR i.sid = 0) 
UNION ALL 
(
SELECT i.id invn_id, 
     IF(ss.serial_id IS NOT NULL,ss.serial_id, NULL) serial_number, 
     -(SUM(IF(ss.serial_id IS NOT NULL, 1.000000, -(i.qty))) - -(i.qty)) qty, -- difference 
     'auto' flag, i.sid site_id, i.prod_id, i.fifo_total_amount, i.trans_date 
FROM inventories i 
INNER JOIN prod p ON p.id = i.prod_id 
LEFT JOIN sale_products sp ON sp.inventory_id = i.id 
LEFT JOIN sale_serial ss ON ss.prod_id = i.prod_id AND ss.sale_id = sp.sale_id 
WHERE i.qty < 0 
     AND ('2015-03-25 00:00:00' IS NULL OR i.trans_date >= '2015-03-25 00:00:00') 
     AND ('2015-03-27 08:27:36' IS NULL OR i.trans_date <= '2015-03-27 08:27:36') 
     AND p.name NOT IN ('Starting Balance' , 'Opening Balance', 'Equity') 
     AND i.prod_id = 7655 AND (0 = 0 OR i.sid = 0) 
GROUP BY i.id -- difference 
HAVING qty > 0 -- difference 
) 
ORDER BY site_id , prod_id , trans_date , qty ASC 

Обратите внимание, что второй оператор (таблица объединения) почти такой же, как и первый оператор, за исключением строк в комментарии. Я доволен результатом, но не удовлетворен запросом из-за его избыточности. Есть ли возможность сделать это краткое изложение?Как я могу упростить запрос без использования UNION ALL?

Выход я хочу получить что-то вроде этого, например:

У меня есть общее количество 5 с идентификатором 95514:

+-------+-----------+---------+ 
| id | qty  | prod_id | 
+-------+-----------+---------+ 
| 95514 | 5.000000 | 7655 | 
+-------+-----------+---------+ 

Если я выполнить запрос выше, результат будет выглядеть следующим образом:

+---------+---------------+----------+------+---------+---------+-------------------+---------------------+ 
| invn_id | serial_number | qty  | flag | site_id | prod_id | fifo_total_amount | trans_date   | 
+---------+---------------+----------+------+---------+---------+-------------------+---------------------+ 
| 95514 | 237658  | 1.000000 | auto |  1 | 7655 |   2763.0194 | 2010-07-22 09:48:24 | 
| 95514 | 237671  | 1.000000 | auto |  1 | 7655 |   2763.0194 | 2010-07-22 09:48:24 | 
| 95514 | 237699  | 1.000000 | auto |  1 | 7655 |   2763.0194 | 2010-07-22 09:48:24 | 
| 95514 | 237658  | 2.000000 | auto |  1 | 7655 |   2763.0194 | 2010-07-22 09:48:24 | 
+---------+---------------+----------+------+---------+---------+-------------------+---------------------+ 

первые три строки вернулись первое утверждение запроса в UNION ALL, а четвертая строка, возвращенная второе утверждение. Если мы будем суммировать qty столбец, мы можем получить значение 5.

ответ

0

я подозреваю, вы хотите group by with rollup:

SELECT i.id invn_id, 
     IF(ss.serial_id IS NOT NULL,ss.serial_id, NULL) serial_number, 
     -(SUM(IF(ss.serial_id IS NOT NULL, 1.000000, -(i.qty))) - -(i.qty)) qty, -- difference 
     'auto' flag, i.sid site_id, i.prod_id, i.fifo_total_amount, i.trans_date 
FROM inventories i 
INNER JOIN prod p ON p.id = i.prod_id 
LEFT JOIN sale_products sp ON sp.inventory_id = i.id 
LEFT JOIN sale_serial ss ON ss.prod_id = i.prod_id AND ss.sale_id = sp.sale_id 
WHERE i.qty < 0 
     AND ('2015-03-25 00:00:00' IS NULL OR i.trans_date >= '2015-03-25 00:00:00') 
     AND ('2015-03-27 08:27:36' IS NULL OR i.trans_date <= '2015-03-27 08:27:36') 
     AND p.name NOT IN ('Starting Balance' , 'Opening Balance', 'Equity') 
     AND i.prod_id = 7655 AND (0 = 0 OR i.sid = 0) 
GROUP BY i.id WITH ROLLUP 
HAVING qty > 0 -- difference 

Однако, я не уверен на 100%, как это вписывается в SELECT логика.

+0

Спасибо @ Gordon, однако, я думаю, что в этом случае мне не нужно «WITH ROLLUP». Я уже редактировал свой вопрос и объяснял результаты, которые я хочу получить. – Chisskarzz

Смежные вопросы