2015-10-17 64 views
2

我在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

回答

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

好像是沒關係,即使工作如果我將file_status_id更改爲eg 2或3。有沒有機會把它放在SQlAlchemy核心中? – lukik

+0

@lukik:對不起,不知道我不使用SQLAlchemy(或任何其他混淆層) –

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; 

SqlFiddle

如果搜索file_status_id只在最新上傳,移動在查詢外子句:

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

這通常在Postgres中有更好的性能。 –

+0

這似乎會返回正確的結果,但當您更改file_status_id時它會中斷。如果你用2代替1代替file_status_id,它仍然會給你一個結果。它似乎正在獲取任何具有指定狀態的文件,即使它不是最新的。 [sqlfiddle for changed file_status_id](http://sqlfiddle.com/#!15/c022d/2)。下面的作品是@a_horse_with_no_name。請確認。 – lukik

+0

這是某種誤解。見編輯的答案。 – klin

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 

http://sqlfiddle.com/#!15/dc955/52

相關問題