Объединение SUM (), GROUP_BY () и LEFT_JOIN () возвращает неверные результаты: как исправить? - PullRequest
1 голос
/ 18 марта 2011

Я пишу запрос, который должен возвращать агрегированные часы для нескольких пользователей в день / месяц / год.

Таблица выглядит примерно так:

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

Как я могу это исправить?

EDIT:

Вот схемы для tag и tag_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 ]

2 голосов
/ 18 марта 2011

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
0 голосов
/ 18 марта 2011

Возможно, вы хотите что-то вроде этого:

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
0 голосов
/ 18 марта 2011
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
...