我被要求在工作中整理一个小型报告系统。我们有一个用户提交信息的数据库,即各种事件的开始和停止时间。
如您所见,事件具有子类别,每个子类别属于一个类别。
我被要求生成一个图表,表示给定日期范围内给定类别事件的总时间。
例如:
Category Name | Total time
**************************
Balloons | 12h
Chalk | 5.5h
我正在努力从连接声明中获得一笔钱。如您所见,为了将总时间量映射到各种类别,我必须首先确定哪些子类别属于哪些类别,然后相应地组织事件。
我承认,我在一次查询中编写此代码时已经死定,而不是编写存储过程或创建临时表。我确信我只能通过连接完成它,但似乎并非如此。 我对任何有效的解决方案完全开放
一项要求;如果给定类别具有无事件,则它仍应显示在结果中,且仅使用默认值0。
这是我到目前为止所做的:
SELECT
event_categories.name,
SUM(TIMESTAMPDIFF(MINUTE,
events.start,
events.stop) / 60) AS timeLost
FROM
events
LEFT JOIN
event_subcategories ON event_subcategories.id = events.subcategory
RIGHT JOIN
event_categories ON event_categories.id = event_subcategories.id
WHERE
events.date BETWEEN '2016-12-01' AND '2016-12-22'
AND events.bed = 1
GROUP BY event_categories.id;
几乎工作,生成一个类别列表,其中包含相关的时间丢失。只有它不显示所有类别,只显示与其相关的事件。
答案 0 :(得分:1)
更改联接的方式。主表应为event_categories
。假设每个类别都有子类别,则可以将INNER JOIN
与event_subcategories
一起使用。最后将LEFT JOIN
与events
一起使用,因为某些子类别可能没有任何事件。
您还在错误的列上加入了event_categories
和event_subcategories
。它应该是event_subcategories.category
,而不是event_subcategory.id
。
当你执行LEFT JOIN
时,子表上的任何条件都应该在ON
子句中,而不是WHERE
。因为任何没有事件的类别都会为所有NULL
列获得event
,因此这些行的条件永远不会成功,并且会像过滤INNER JOIN
一样被过滤掉。< / p>
SELECT
c.name,
SUM(TIMESTAMPDIFF(MINUTE,
e.start,
e.stop) / 60) AS timeLost
FROM event_categories AS c
JOIN event_subcategories AS s ON s.category = c.id
LEFT JOIN events AS e ON e.subcategory = s.id
AND e.date BETWEEN '2016-12-01' AND '2016-12-22'
AND e.bed = 1
GROUP BY c.id;