我在Postgresql中有一个微不足道的请求,但我无法破解它。
SQLFiddle:http://sqlfiddle.com/#!15/dc955/31
文件上传表:
id file_name
1 file001
2 file002
3 file003
4 file004
文件状态表:
id file_upload_id file_status_id status_date
1 1 1 October, 16 2015 19:22:51
2 1 2 October, 17 2015 09:19:20
3 1 3 October, 17 2015 09:20:51
4 1 4 October, 17 2015 09:22:51
5 2 1 October, 17 2015 13:45:10
6 3 1 October, 17 2015 09:22:57
7 1 1 October, 17 2015 23:22:12
配置文件状态:
id status_code status_name
1 001 Unprocessed
2 002 Queued
3 003 Staging
4 004 Production
有三张桌子: file_upload < - > file_status < - >的 config_file_status 即可。 file_status 表保存文件在处理期间可以经历的各种状态
我需要的是获取file_upload.id, file_upload.file_name, file_status.file_status_id
最新/最新file_status_id = 1
的文件,即未处理的文件,这实际上是上传文件最初上传时创建的状态
到目前为止我已经尝试过了:
select file_upload.file_name,
max(file_status.file_status_id) as latest_status
from file_upload, file_status, config_file_status
where file_upload.id = file_status.file_upload_id and
file_status.file_status_id = config_file_status.id
Group By file_upload.file_name;
它不仅没有返回file001的正确最新状态,而且查询感觉像是过度杀戮。
正在寻找的是用于实现上述目的的正确SQL语法,但如果可以的话,也在SQLAlchemy Core中提供相同的语法。
使用Postgresql 9.3
答案 0 :(得分:4)
您可以使用distinct on (s.file_upload_id)
。将status_date desc
放入order by
以获取每个文件的最新上传日期。
select distinct on (s.file_upload_id)
s.file_upload_id,
u.file_name,
s.file_status_id
from file_status s
join file_upload u on u.id = s.file_upload_id
where file_status_id = 1
order by file_upload_id, status_date desc;
如果仅在最新上传中搜索file_status_id
,请移动查询外的where子句:
select *
from (
select distinct on (s.file_upload_id)
s.file_upload_id,
u.file_name,
s.file_status_id
from file_status s
join file_upload u on u.id = s.file_upload_id
order by file_upload_id, status_date desc
) sub
where file_status_id = 2;
答案 1 :(得分:3)
通常使用window function:
解决此类问题select id, file_name, status_date, file_status_id
from (
SELECT fu.id,
fu.file_name,
fs.status_date,
fs.file_status_id,
row_number() over (partition by fu.id order by fs.status_date desc) as rn
FROM file_upload fu
LEFT JOIN file_status fs ON fu.id = fs.file_upload_id
) t
where rn = 1
and file_status_id = 1
order by id, file_name;
答案 2 :(得分:1)
select u.id, u.file_name, s.file_status_id, s.status_date
from
file_upload u, file_status s
where u.id = s.file_upload_id
and
s.status_date = (select max(s.status_date) from file_status s
where u.id = s.file_upload_id) and s.file_status_id = 1