2013-12-10 120 views
0

我想通過集合函數使用聯合和組,但所有嘗試都會導致缺少行或不正確的數據。下面是產生我所需要的數據的兩個疑問,現在我只需要團結他們分組和按聚合函數

這裏是pastebin

SQL查詢#1的樣本SQL轉儲:

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 | 
+----------+------------+------------+ 

這是我在使用聯盟的兩個表

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

你能展示你想要的結果嗎?在第一個查詢中,您將'total_inst'設置爲0.使用您的表格結構編輯您的文章,您嘗試的結果以及您想要的結果。幫助你會容易得多。 –

+0

編輯顯示我所追求的結果。 @JorgeCampos,在SQL 1中'total_inst'(總安裝收入)爲0,在sql 2中'total_prod'(總產品收入)爲0,因爲訂單可以有產品和/或安裝,並且我希望結果能夠顯示0代表'total_inst'和0'total_prod'。 – cborgia

回答

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結果中的記錄(相反的情況)。 A 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

+0

此ALSMOT生成我正在查找的結果,但未能顯示'total_prod'或'total_inst'列中的值爲0的訂單。例如,使用這個sql,order_id 6不會被返回(請參閱編輯的問題以獲得所需的結果) – cborgia

+0

Ahhh那麼您需要一個外部連接,而不是由where子句「where q1.order_id = q2」生成的默認內部連接。 ORDER_ID「。我會更新上述答案。 –

+0

馬特,你編輯的查詢確實產生了期望的結果,但它看起來並不理想(可能不是最理想的路線)。我會繼續玩這個遊戲,如果沒有人用更短的工作查詢提交,我會將你的答案標記爲正確的。 – cborgia

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; 

1st編輯: 好吧。所以基本上,如果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); 

這是如何工作的?這可能非常不理想,但希望能得到結果。

+0

這太ALMOST產生我正在尋找的結果,與Matt的第一個查詢相同的問題(當total_prod/total_inst中的值爲0時缺少行) – cborgia