我有4张桌子:
projects: id, title, current_status_id
statuses: id, label
status_history: project_id, status_id, created_at
messages: id, project_id, body, created_at
当在应用程序中,项目更改状态(例如,从"引导"到"活动"到"完成")时,将插入status_history行。请注意,created_at列是记录更改日期的时间戳。在状态更改之间,项目中正在发生活动并创建消息。例如,项目初始化为" lead"状态,一些消息是在项目进入这个"领导"州,项目改为"活跃"状态,在项目处于此状态时创建一些消息,依此类推。
我想创建一个查询,显示:日期,"引导"中创建的消息数量。项目,#在"活动"中创建的消息项目和具有其他状态的项目中的#消息。这可以在一个查询中完成吗?我正在使用PostgreSQL。
这是一些伪代码,希望能够阐明我正在寻找的东西。
* Start at the earliest date
* Find all projects whose status was 'lead' on that date
* Count the number of created messages from these projects with that date
* Find all projects whose status was 'active' on that date
* Count the number of created messages from these projects with that date
* Find all projects whose status was anything else on that date
* Count the number of created messages from these projects with that date
* ... some projects change status, some stay the same, business happens ...
* Go to next date
* Find all projects whose status was 'lead' on that date
* Count the number of created messages from these projects with that date
* Find all projects whose status was 'active' on that date
* Count the number of created messages from these projects with that date
* Find all projects whose status was anything else on that date
* Count the number of created messages from these projects with that date
* ... some projects change status, some stay the same, business happens ...
* keep doing this until the present
虽然项目确实有一个current_status_id列,但它是当前状态,不一定是上个月项目的状态。项目的状态不会每天都在变化 - 每个项目都不会每天创建一个status_history行。
答案 0 :(得分:0)
您正在寻找这样的查询......这是MSSQL但我假设与Postgresql非常相似,或者您可以在线找到正确的语法。
SELECT count(*) AS 'count', messages.created_at, statuses.label
FROM messages
JOIN projects ON projects.id = messages.project_id
JOIN status_history ON projects.id = status_history.project_id
JOIN statuses ON statuses.id ON status_history.status_id
GROUP BY created_at, statues.label
答案 1 :(得分:0)
尝试以下内容。
将“lead”和“active”替换为这两种状态的状态ID。
请注意,所选的第一个字段是将created_at时间戳转换为日期值(删除时间)。
提供的计数显示了使用这些状态新创建的项目数。它们不包括已经存在但在给定日期更改为这些状态的项目。这是通过not exists子查询完成的。
select date(created_at) as dt
, sum(case when sh.status_id = 'lead' then 1 else 0 end) as num_lead
, sum(case when sh.status_id = 'active' then 1 else 0 end) as num_active
, sum(case when sh.status_id not in ('lead','active') then 1 else 0 end) as num_else
from status_history sh
where not exists
( select 1
from status_history x
where x.project_id = sh.project_id
and x.created_at < sh.created_at )
group by date(created_at)
order by 1
答案 2 :(得分:0)
怎么样:
SELECT to_char(tmp.date, 'YYYY-MM-DD') as date, COUNT(tmp.status = 'lead') as num_lead, COUNT(tmp.status = 'active') as num_active FROM
(
SELECT m.created_at AS date, COUNT(m.id) as messages, s.label as status FROM messages AS m
INNER JOIN project AS p ON p.id = m.project_id
INNER JOIN statuses AS s ON s.id = p.current_status_id
GROUP BY m.created_at, s.id, s.label
) as tmp
GROUP BY tmp.date;
分组应该是100%正确的(因为它不清楚一个id只属于一个文本表示,标签不是primary_key!)
临时表包含&#34;每个日期的消息和project_status_label&#34;的所有关系。外部选择函数只改变维度。