我使用PostgreSQL并拥有以下表格:
users id name 1 joe 2 jack
projects id name 1 p1 2 p2
tasks id name user_id project_id due_on 1 t1 1 1 2015-02-17 2 t2 1 2 2015-02-18 3 t3 2 1 2015-02-19
我想构建一个查询,为2012-01-01之后至少有一个任务到期的每个用户返回一行。它应列出用户名,用户的任务数,最远任务的日期以及与此最远任务相关联的项目名称。
使用上面的表格,结果应为
user_name max_due_on task_count project_name joe 2015-02-18 2 p2 jack 2015-02-19 1 p1
我构建了以下查询,但它缺少与最远的到期任务相关联的项目名称。
SELECT
users.name AS user_name,
max(tasks.due_on) AS max_due_on,
count(*) AS task_count
FROM tasks
LEFT JOIN users ON users.id = tasks.user_id
LEFT JOIN projects ON projects.id = tasks.project_id
WHERE
tasks.due_at > '2012-01-01'
GROUP BY users.name
有没有办法达到我的需要?
编辑:是工作查询,稍微改编自Bulat的anwer:
SELECT user_name, due_at, task_count, project_name
from (
SELECT
users.name AS user_name,
projects.name AS project_name,
tasks.due_on,
count(*) OVER (PARTITION BY users.name) AS task_count,
row_number() over (PARTITION BY users.name ORDER BY tasks.due_on DESC) AS rn
FROM tasks
LEFT JOIN users ON users.id = tasks.user_id
LEFT JOIN projects ON projects.id = tasks.project_id
WHERE tasks.due_on > '2012-01-01'
) t
WHERE rn = 1
ORDER by user_name
答案 0 :(得分:1)
你应该尝试这样的事情:
select user_name, due_on, task_count, project_name
from (
SELECT
users.name,
projects.project_name,
tasks.due_on,
count(*) over (partition by user_name, project_name order by id desc) as AS task_count,
row_number() over (partition by user_name, project_name order by id desc) as rn
FROM tasks
LEFT JOIN users ON users.id = tasks.user_id
LEFT JOIN projects ON projects.id = tasks.project_id
WHERE
tasks.due_at > '2012-01-01'
) t
where rn = 1
order by id;