我正在尝试使用union和group by聚合函数,但所有尝试都会导致缺少行或数据不正确。下面是两个产生我需要的数据的查询,现在我只需要将它们联合起来
以下是pastebin
上的SQL转储示例SQL查询#1:
SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst
FROM orders as o, orders_product_line as opl, products as p
WHERE opl.order_id = o.id
AND p.id = opl.product_id
GROUP BY o.id
查询#1的结果
+----------+------------+------------+
| order_id | total_prod | total_inst |
+----------+------------+------------+
| 1 | 4200 | 0 |
| 2 | 40000 | 0 |
| 3 | 3600000 | 0 |
| 4 | 44500 | 0 |
| 5 | 1229800 | 0 |
| 6 | 45000000 | 0 |
+----------+------------+------------+
SQL查询#2:
SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst
FROM orders as o, orders_installation_line as oil, installations as i
WHERE oil.order_id = o.id
AND i.id = oil.intallation_id
GROUP BY order_id
查询#2的结果:
+----------+------------+------------+
| order_id | total_prod | total_inst |
+----------+------------+------------+
| 1 | 0 | 4675 |
| 2 | 0 | 255000 |
| 3 | 0 | 18880 |
| 4 | 0 | 600 |
| 5 | 0 | 3540 |
+----------+------------+------------+
这是我尝试在两个表中使用union
SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id GROUP BY o.id
UNION ALL
SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id GROUP BY order_id
结果
+----------+------------+------------+
| order_id | total_prod | total_inst |
+----------+------------+------------+
| 1 | 4200 | 0 |
| 2 | 40000 | 0 |
| 3 | 3600000 | 0 |
| 4 | 44500 | 0 |
| 5 | 1229800 | 0 |
| 6 | 45000000 | 0 |
| 1 | 0 | 4675 |
| 2 | 0 | 255000 |
| 3 | 0 | 18880 |
| 4 | 0 | 600 |
| 5 | 0 | 3540 |
+----------+------------+------------+
最后,这是我在阅读堆栈溢出的其他答案后尝试使用union:
SELECT *
FROM
(
SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst
FROM orders as o, orders_product_line as opl, products as p
WHERE opl.order_id = o.id
AND p.id = opl.product_id
GROUP BY o.id
UNION ALL
SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst
FROM orders as o, orders_installation_line as oil, installations as i
WHERE oil.order_id = o.id
AND i.id = oil.intallation_id
GROUP BY order_id
) Q
GROUP BY Q.order_id
最后一次结合的结果:
+----------+------------+------------+
| order_id | total_prod | total_inst |
+----------+------------+------------+
| 1 | 4200 | 0 |
| 2 | 40000 | 0 |
| 3 | 3600000 | 0 |
| 4 | 44500 | 0 |
| 5 | 1229800 | 0 |
| 6 | 45000000 | 0 |
+----------+------------+------------+
我错过了什么?我需要最后一列total_inst
来显示值。这是我要找的结果:
+----------+------------+------------+
| order_id | total_prod | total_inst |
+----------+------------+------------+
| 1 | 4200 | 4675 |
| 2 | 40000 | 255000 |
| 3 | 3600000 | 18880 |
| 4 | 44500 | 600 |
| 5 | 1229800 | 3540 |
| 6 | 45000000 | 0 |
+----------+------------+------------+
答案 0 :(得分:0)
你的小组是对的......但我认为你不想要一个工会。试试这个:
select q1.order_id, q1.total_prod, q2.total_inst from
(SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id GROUP BY o.id) q1,
(SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id GROUP BY order_id) q2
where q1.order_id = q2.order_id
编辑:上面的查询只会检索由两个内部查询返回的order_ids。要包含order_id 6,您需要 LEFT JOIN 。但是,这不会得到q2结果中可能存在的记录,但不会得到q1的结果(相反的情况)。 FULL JOIN 会这样做,但我的理解是这些都没有在MySQL中实现。它们可以被模拟,如下所述:Full Outer Join in MySQL
select q1.order_id, q1.total_prod, q2.total_inst from
(SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id GROUP BY o.id) q1
LEFT JOIN
(SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id GROUP BY order_id) q2
ON q1.order_id = q2.order_id
UNION
select q1.order_id, q1.total_prod, q2.total_inst from
(SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id GROUP BY o.id) q1
RIGHT JOIN
(SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id GROUP BY order_id) q2
ON q1.order_id = q2.order_id
最终编辑:这是另一种方法的工作SQLFiddle。 http://sqlfiddle.com/#!2/deff12/12/0
答案 1 :(得分:0)
我同意马特的观点,你在这里需要的是加入/笛卡尔产品,而不是工会。尝试:
SELECT * FROM
(SELECT o.id as order_id, SUM(price * quantity) as total_prod, FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id GROUP BY o.id) as q1 NATURAL JOIN
(SELECT o.id as order_id, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id GROUP BY order_id) as q2;
第一次编辑:
好的。所以基本上,如果id在orders_product_line而不是orders_installation_line,那么我们需要插入一个带有id的元组,total_prod的值和total_inst的值0。那是对的吗?所以尝试这样的事情:
(SELECT * FROM
(SELECT o.id as order_id, SUM(price * quantity) as total_prod, FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id GROUP BY o.id) as q1 NATURAL JOIN
(SELECT o.id as order_id, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id GROUP BY order_id) as q2)
UNION
(SELECT o.id as order_id, SUM(price * quantity) as total_prod, 0 as total_inst FROM orders as o, orders_product_line as opl, products as p WHERE opl.order_id = o.id AND p.id = opl.product_id AND opl.order_id NOT IN (SELECT id FROM orders_installation_line) GROUP BY o.id)
UNION
(SELECT o.id as order_id, 0 as total_prod, SUM(rate * hours) as total_inst FROM orders as o, orders_installation_line as oil, installations as i WHERE oil.order_id = o.id AND i.id = oil.intallation_id AND oil.order_id NOT IN (SELECT id FROM orders_product_line) GROUP BY order_id);
这是如何工作的?它可能非常不理想,但希望它能得到结果。