mysql - 如何在不使用 UNION ALL 的情况下简化查询?

标签 mysql

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

观察到,除了注释中的行之外,第二条语句(联合表)与第一条语句几乎相同。我对结果感到满意,但对查询不满意,因为它的冗余。是否有可能简要介绍一下?

我想要得到的输出是这样的,例如:

我的总数量为 5,ID 为 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。

最佳答案

我怀疑您想要通过汇总进行分组:

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 逻辑。

关于mysql - 如何在不使用 UNION ALL 的情况下简化查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29292405/

相关文章:

mysql - 这个mysql创建表查询有什么问题?

mysql 两个具有相同条目名称的表相加值

mysql - 为用户帐户编写系统

php - 尝试使用 PHP 从 mysql 中使用纬度和经度查找商店位置

php - 检索列的几个选定行的总和?

mysql - 有没有比数据库更好的地方来存储大量未使用的数据?

php - 为什么 "--comment"不工作而 "-- comment"工作?

mysql - 如何在MySQL中没有连续ID的两个连续行之间进行DATEDIFF?

mysql - 返回两个连续结果之间的 "diff"

java - MySQL 查询使用逻辑操作获取数据列表