我有一张表,其中包含服务器停机时间的记录
我在sqlfiddle创建了这个表的简化版本。请看这里sqlfiddle
该表有每个记录,如
Reason Month Down_Time
A May 2
A May 5
B May 5
C July 15
A July 3
B June 6
A June 8
C June 2
如果没有匹配的记录,我需要编写一个查询来获取给予Month和Reason的所有组合为NULL 举个例子:如果由于原因A,B或D,我需要在5月,6月和7月获得系统的停机时间..我期待的是......
Reason Month DOWNTIME
A May 7
A June 8
A July 3
B May 5
B June 6
B July NULL
D May NULL
D June NULL
D July NULL
由于我们在给定月份的记录中没有D,因此它应该为NULL
这是我的查询:
SELECT Reasons.reason, Months.Month,sum( a.Down_time ) AS downtime
FROM tabledown a
RIGHT JOIN (
SELECT 'A' AS reason
UNION ALL SELECT 'B' AS reason
UNION ALL SELECT 'D' AS reason
) Reasons
ON a.reason = Reasons.reason
RIGHT JOIN (
SELECT 'May' AS month
UNION ALL SELECT 'June' AS month
UNION ALL SELECT 'July' AS month
) Months
ON a.Month = Months.month
GROUP BY Reasons.reason,Months.month
ORDER BY Reasons.reason
为什么我没有得到预期的输出:(
答案 0 :(得分:4)
| REASON | MONTH | ------------------- | A | May | | A | May | | A | July | | A | June | | B | May | | B | June | | D | (null) |
但是,因为如果连接条件满足至少一次,则外连接会产生结果(如果条件从不满足,则仅引入NULL
条记录) ,your second outer join然后不会生成(B, July)
的记录;它也完全丢弃了Reason = 'D'
,因为连接条件没有得到满足(所有三个月都在其他地方得到满足):
| REASON | MONTH | ------------------ | A | May | | A | May | | B | May | | A | June | | B | June | | A | July |
虽然您可以解决Reason = 'D'
by adding OR a.Month IS NULL
对您的加入条件的损失,但您仍然不会生成(B, July)
。相反,因为您希望获得每对(Reason, Month)
,所以您必须CROSS JOIN
使用您的具体化Reasons
表格Months
表:
SELECT Reason, Month
FROM
(
SELECT 'A' AS Reason
UNION ALL SELECT 'B'
UNION ALL SELECT 'D'
) Reasons CROSS JOIN (
SELECT 'May' AS Month
UNION ALL SELECT 'June'
UNION ALL SELECT 'July'
) Months
| REASON | MONTH | ------------------ | A | May | | B | May | | D | May | | A | June | | B | June | | D | June | | A | July | | B | July | | D | July |
在sqlfiddle上查看。
然后,您只需要将结果外部连接到基础数据:
SELECT Reason, Month, SUM(Down_time) downtime
FROM
(
SELECT 'A' AS Reason
UNION ALL SELECT 'B'
UNION ALL SELECT 'D'
) Reasons CROSS JOIN (
SELECT 'May' AS Month
UNION ALL SELECT 'June'
UNION ALL SELECT 'July'
) Months
LEFT JOIN tabledown USING (Reason, Month)
GROUP BY Reason, Month
| REASON | MONTH | DOWNTIME | ----------------------------- | A | July | 3 | | A | June | 8 | | A | May | 7 | | B | July | (null) | | B | June | 6 | | B | May | 5 | | D | July | (null) | | D | June | (null) | | D | May | (null) |
在sqlfiddle上查看。