如果没有匹配的记录,MySql查询将获得两列的所有组合(MySql query to get all combinations of two columns with NULL if there is

编程入门 行业动态 更新时间:2024-10-22 02:38:02
如果没有匹配的记录,MySql查询将获得两列的所有组合(MySql query to get all combinations of two columns with NULL if there is no matching record)

我有一个表,其中包含服务器停机时间的记录。 我在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

为什么我没有得到预期的输出:(

I have a Table which has the records of the down time of a server. I have created a simplified version of this table at sqlfiddle. Please see here sqlfiddle The table has each record like

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

I need to write a query to get all combinations of give Month and Reason with NULL if there is no matching record As an example : If I need to get the down time of the system in May, June and July due to Reason A,B or D.. What I am expecting is..

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

Since we don't have D in the records for given months, it should be NULL This is my Query:

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

Why i am not getting the expected output :(

最满意答案

正如预期的那样, 您的第一个外连接会产生:

| REASON | MONTH | ------------------- | A | May | | A | May | | A | July | | A | June | | B | May | | B | June | | D | (null) |

但是,因为如果连接条件至少满足一次 (如果条件永远不满足则只引入NULL记录),则外连接会产生结果,因此第二个外连接 不会产生(B, July)的记录; 它也完全丢弃了Reason = 'D' ,因为连接条件没有得到满足(并且所有三个月都在其他地方得到满足):

| REASON | MONTH | ------------------ | A | May | | A | May | | B | May | | A | June | | B | June | | A | July |

虽然你可以 通过在你的连接条件中添加 OR a.Month IS NULL来解决Reason = 'D'的丢失,但你仍然不会产生(B, July) 。 相反,因为您想要获得每对(Reason, Month) ,您必须使用物化Months表CROSS JOIN您的物化Reasons表:

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上看到它。

Your first outer join, as expected, produces:

| REASON | MONTH | ------------------- | A | May | | A | May | | A | July | | A | June | | B | May | | B | June | | D | (null) |

However, because outer joins produce results if the join condition is satisfied at least once (and only introduce NULL records if the condition is never satisfied), your second outer join then does not produce a record for (B, July); it also drops Reason = 'D' entirely, because the join condition is not met (and all three months have been satisfied elsewhere):

| REASON | MONTH | ------------------ | A | May | | A | May | | B | May | | A | June | | B | June | | A | July |

Whilst you could resolve the loss of Reason = 'D' by adding OR a.Month IS NULL to your join condition, you still will not produce (B, July). Instead, because you want to obtain every pair of (Reason, Month), you must CROSS JOIN your materialised Reasons table with your materialised Months table:

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 |

See it on sqlfiddle.

You then merely need outer join the result with your underlying data:

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

See it on sqlfiddle.

更多推荐

本文发布于:2023-08-04 22:47:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1423332.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组合   如果没有   query   combinations   MySql

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!