从另一个表标识的表中连接数据

时间:2016-12-22 23:33:08

标签: mysql join

我被要求在工作中整理一个小型报告系统。我们有一个用户提交信息的数据库,即各种事件的开始和停止时间。

DB的相关表格: enter image description here

如您所见,事件具有子类别,每个子类别属于一个类别。

我被要求生成一个图表,表示给定日期范围内给定类别事件的总时间。

例如:

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;

几乎工作,生成一个类别列表,其中包含相关的时间丢失。只有它不显示所有类别,只显示与其相关的事件。

1 个答案:

答案 0 :(得分:1)

更改联接的方式。主表应为event_categories。假设每个类别都有子类别,则可以将INNER JOINevent_subcategories一起使用。最后将LEFT JOINevents一起使用,因为某些子类别可能没有任何事件。

您还在错误的列上加入了event_categoriesevent_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;