合并SUM(),GROUP_BY()和LEFT_JOIN()会返回不正确的结果:如何修复?

时间:2011-03-18 14:39:31

标签: mysql group-by left-join

我正在编写一个查询,该查询应该返回每天/每月/每年多个用户的汇总小时数。

表格如下所示:

+------------------------------------------+
| id | entity_id | minutes | person | date |
+------------------------------------------+

输出应该的外观:

+----------------------------+
| year | month | day | hours |
| 2008 | 12    | 1   | 30    |
| 2008 | 12    | 2   | 40    |
| 2008 | 12    | 3   | 23    |
+----------------------------+

相反,由于hours导致返回的行,left join通常会更多。

问题是我需要根据链接到相应实体的标记查询此表。当我加入提供链接的tag_entity和提供实际标记名称的tags时,我的SUM()不再有效,因为返回的结果太多了。

查询:

select 
    date_format(from_unixtime(date), '%Y-%m-%d') as myDate,
    ROUND(SUM(time) / 60,1) as hours

from time h

left join tag_entity te on te.entity_id = h.entity_id
left join tags t on t.tag_id = te.tag_id

where (t.tag_name NOT IN ('foo', 'bar', 'baz') OR t.tag_name IS NULL) 

group by
    myDate

order by
    hours DESC, myDate ASC

我该如何解决这个问题?

编辑:

以下是tagtag_entity的模式:

Tag

+----------+-------------+
| Field    | Type        |
+----------+-------------+
| tag_id   | int(11)     |
| tag_name | varchar(50) |
+----------+-------------+

tag_entity

+-----------+---------+
| Field     | Type    |
+-----------+---------+
| id        | int(11) |
| tag_id    | int(11) |
| entity_id | int(11) |
+-----------+---------+

3 个答案:

答案 0 :(得分:2)

GROUP BY结果分组,而不是分别对表行进行分组。

根据您的评论仅返回时间表中未链接到其中一个标记的行

SELECT 
    date_format(from_unixtime(date), '%Y-%m-%d') as myDate,
    ROUND(SUM(time) / 60,1) as hours
FROM `time` h
  LEFT JOIN (
    SELECT DISTINCT te.entity_id
    FROM tag_entity te
      LEFT JOIN tags t on t.tag_id = te.tag_id
    WHERE te.entity_id IS NOT NULL AND t.tag_name IN ('foo', 'bar', 'baz')
  ) g ON h.entity_id = g.entity_id
WHERE g.entity_id IS NULL
group by
    myDate

order by
    hours DESC, myDate ASC

答案 1 :(得分:0)

select 
    date_format(from_unixtime(date), '%Y-%m-%d') as jaar,
    ROUND(SUM(time) / 60,1) as uren

from time h

left join tag_entity te on te.entity_id = h.entity_id
left join tags t on t.tag_id = te.tag_id

where (t.tag_name NOT IN ('foo', 'bar', 'baz') OR t.tag_name IS NULL) 

group by jaar

order by
    uren DESC, jaar ASC

答案 2 :(得分:0)

可能你想要这样的东西:

select 
    date_format(from_unixtime(date), '%Y-%m-%d') as myDate,
    ROUND(SUM(time) / 60,1) as hours

from time h

<击>     left join tag_entity te on te.entity_id = h.entity_id

where NOT EXISTS(select te.entity_id

                 from tag_entity te

                 join tags t on t.tag_id = te.tag_id

                 where te.tag_entity = h.entity_id  AND t.tag_name IN ('foo', 'bar', 'baz')) 

group by
    myDate

order by
    hours DESC, myDate ASC