2011-06-14 123 views
3

下面是一個查詢組以小時爲單位的交易通過pricepoint:MySQL的左外連接的麻煩

SELECT hour(Stamp) AS hour, PointID AS pricepoint, count(1) AS counter 
FROM Transactions 
GROUP BY 1,2; 

輸出示例:

+------+------------+---------+ 
| hour | pricepoint | counter | 
+------+------------+---------+ 
| 0 |   19 |  5 | 
| 0 |   20 |  14 | 
| 1 |   19 |  3 | 
| 1 |   20 |  12 | 
| 2 |   19 |  2 | 
| 2 |   20 |  8 | 
| 3 |   19 |  2 | 
| 3 |   20 |  4 | 
| 4 |   19 |  1 | 
| 4 |   20 |  1 | 
| 5 |   19 |  4 | 
| 5 |   20 |  1 | 
| 6 |   20 |  2 | 
| 8 |   19 |  1 | 
| 8 |   20 |  4 | 
| 9 |   19 |  2 | 
| 9 |   20 |  5 | 
| 10 |   19 |  6 | 
| 10 |   20 |  1 | 
| 11 |   19 |  10 | 
| 11 |   20 |  2 | 
| 12 |   19 |  10 | 
| 12 |   20 |  3 | 
| 13 |   19 |  10 | 
| 13 |   20 |  10 | 
| 14 |   19 |  8 | 
| 14 |   20 |  3 | 
| 15 |   19 |  6 | 
| 15 |   20 |  8 | 
| 16 |   19 |  11 | 
| 16 |   20 |  10 | 
| 17 |   19 |  7 | 
| 17 |   20 |  17 | 
| 18 |   19 |  7 | 
| 18 |   20 |  9 | 
| 19 |   19 |  10 | 
| 19 |   20 |  12 | 
| 20 |   19 |  17 | 
| 20 |   20 |  11 | 
| 21 |   19 |  12 | 
| 21 |   20 |  29 | 
| 22 |   19 |  6 | 
| 22 |   20 |  21 | 
| 23 |   19 |  9 | 
| 23 |   20 |  23 | 
+------+------------+---------+ 

正如你可以看到,幾個小時都沒有交易(例如早上7點),有些小時只有單個價位的交易(例如上午6點,只有價格點20,但沒有價格點19的交易)。

我想在沒有事務的情況下顯示結果集爲「0」,而不是像現在那樣不在那裏。

嘗試使用左外部連接。該inHour表中包含的值0..23

SELECT H.hour, PointID AS Pricepoint, COALESCE(T.counter, 0) AS Count 
FROM inHour H 
LEFT OUTER JOIN 
(
SELECT hour(Stamp) AS Hour, PointID, count(1) AS counter 
FROM Transactions 
GROUP BY 1,2 
) T 
ON T.Hour = H.hour; 

這將產生以下輸出(截斷簡潔):

| 5 |   19 |  4 | 
| 5 |   20 |  1 | 
| 6 |   20 |  2 | 
| 7 |  NULL |  0 | 
| 8 |   19 |  1 | 
| 8 |   20 |  4 | 

我想其實會是什麼:

| 5 |   19 |  4 | 
| 5 |   20 |  1 | 
| 6 |   19 |  0 | 
| 6 |   20 |  2 | 
| 7 |   19 |  0 | 
| 7 |   20 |  0 | 
| 8 |   19 |  1 | 
| 8 |   20 |  4 | 

在我期望的輸出中,值「0」放在價格點旁邊,在給定小時內沒有交易。

您的建議將受到歡迎!謝謝。

+0

也許左連接上一個子查詢,你選擇所有不同pricepoints?否則,我會用價格點的維度表。 – 2011-06-14 12:34:35

+0

事實上,這正是我最終做的,受到了安德魯答案的啓發。 – emx 2011-06-15 06:34:36

回答

3
SELECT h.Hour, p.Pricepoint, COUNT(t.*) AS Count 
FROM inHour h, 
(SELECT DISTINCT PointId AS Pricepoint FROM Transactions) p 
LEFT OUTER JOIN Transactions t 
ON h.Hour = hour(t.Stamp) AND p.Pricepoint = t.PointID 
GROUP BY h.Hour, p.Pricepoint 
ORDER BY h.Hour, p.Pricepoint 

我現在沒有時間去試試這個,所以讓我知道如果它不起作用,我會盡量調整。

+0

謝謝安德魯,這真的啓發了我,我能夠使用你的例子使它工作。 – emx 2011-06-15 06:32:14

0

有人可能有比這更好的解決辦法,但我會用UNION把事情簡單化:

SELECT hour(Stamp) AS hour, PointID AS pricepoint, count(1) AS counter 
FROM Transactions 
GROUP BY 1,2 

UNION 

SELECT hour,0 AS pricepoint,0 AS counter FROM inHour WHERE hour NOT IN (SELECT hour(Stamp) FROM Transactions) 
+0

工會?不確定這是否是最佳解決方案... – 2011-06-14 12:49:15