复杂分组查询(递归?)

时间:2010-10-09 05:59:19

标签: sql postgresql group-by

对不起标题,但我不知道该怎么称呼它。我正在使用PostgreSQL 8.3,并且可以使用非ansi查询提议。

假设这个架构:

TimeEntries
id              - int
entry_date      - date
tracked_seconds - int
project_id      - int

projects
id              - int
name            - string
path            - string

项目是hirachical,我不关心parent_id等,而是我选择了路径列,例如:

Renovate Home    - path = renovate-home
- Clean Kitchen  - path = renovate-home/clean-kitchen

我想要一个返回以下内容的查询:

date - project_path - tracked_seconds(this project) - tracked_seconds (total of self and child projects)

按日期分组,每个项目路径多次,因此示例数据:

projects
name          path
Funny         funny
- Project     funny/project
-- Is Funny   funny/project/is-funny
Foo           foo
- Bar         foo/bar

如果现在有针对funny / project和foo / bar的TimeEntries并且我发出此查询:

SELECT         entry_date, p.path as project_path, sum(tracked_seconds) / 60
FROM           time_entries te
LEFT JOIN      projects p on te.project_id = p.id
GROUP BY       entry_date, p.path

我得到了这个结果:

entry_date        project_path           ?sum?
2010-10-01        funny/project          20
2010-10-01        foo/bar                10

我想要的是:

entry_date        project_path           direct_sum     total
2010-10-01        funny                  0              20
2010-10-01        funny/project          20             20 
2010-10-01        foo                    0              10
2010-10-01        foo/bar                10             10

2 个答案:

答案 0 :(得分:0)

此查询应该让您更接近目标:

SELECT         entry_date, p.path as project_path, p2.path, sum(tracked_seconds) / 60
FROM           time_entries te
LEFT JOIN      projects p on te.project_id = p.id
LEFT JOIN      projects p2 on p2.path LIKE p.path + '/%'
GROUP BY       entry_date, p.path, p2.path

答案 1 :(得分:0)

你是坚持8.3还是升级到8.4?

因为使用8.4,我认为这可以使用窗口函数来解决:

SELECT te.entry_date, 
       te.tracked_seconds, 
       p.path, 
       sum(tracked_seconds) over (partition by (string_to_array(path, '/'))[1] order by entry_date asc, path desc)
FROM TimeEntries te
 JOIN projects p ON te.project_id = p.id
ORDER BY entry_date