嘿,我在PostgreSql中有2个表:
1 - documents: id, title
2 - updates: id, document_id, date
Run Code Online (Sandbox Code Playgroud)
和一些数据:
文件:
| 1 | Test Title |
Run Code Online (Sandbox Code Playgroud)
更新:
| 1 | 1 | 2006-01-01 |
| 2 | 1 | 2007-01-01 |
| 3 | 1 | 2008-01-01 |
Run Code Online (Sandbox Code Playgroud)
因此,所有更新都指向同一文档,但所有更新都具有不同的更新日期.
我想要做的是从文档表中进行选择,但也包括基于日期的最新更新.
这样的查询应该怎么样?这是我目前拥有的,但我列出了所有更新,而不是我需要的最新更新:
SELECT * FROM documents,updates WHERE documents.id=1 AND documents.id=updates.document_id ORDER BY date
Run Code Online (Sandbox Code Playgroud)
包括; 我在查询中需要这个的原因是我想从更新模板的日期订购!
编辑:此脚本大大简化,因此我应该能够创建一个返回任意数量结果的查询,但包括最新更新日期.我正在考虑使用内连接或左连接或类似的东西!?
Qua*_*noi 25
使用PostgreSQL扩展名DISTINCT ON:
SELECT DISTINCT ON (documents.id) *
FROM document
JOIN updates
ON updates.document_id = document_id
ORDER BY
documents.id, updates.date DESC
Run Code Online (Sandbox Code Playgroud)
这将按顺序从每个document.id群集中获取第一行ORDER BY.
要检查的测试脚本:
SELECT DISTINCT ON (documents.id) *
FROM (
VALUES
(1, 'Test Title'),
(2, 'Test Title 2')
) documents (id, title)
JOIN (
VALUES
(1, 1, '2006-01-01'::DATE),
(2, 1, '2007-01-01'::DATE),
(3, 1, '2008-01-01'::DATE),
(4, 2, '2009-01-01'::DATE),
(5, 2, '2010-01-01'::DATE)
) updates (id, document_id, date)
ON updates.document_id = documents.id
ORDER BY
documents.id, updates.date DESC
Run Code Online (Sandbox Code Playgroud)
pil*_*row 10
您可以创建一个派生表,其中只包含每个document_id的最新"更新"记录,然后加入"文档":
SELECT d.id, d.title, u.update_id, u."date"
FROM documents d
LEFT JOIN
-- JOIN "documents" against the most recent update per document_id
(
SELECT recent.document_id, id AS update_id, recent."date"
FROM updates
INNER JOIN
(SELECT document_id, MAX("date") AS "date" FROM updates GROUP BY 1) recent
ON updates.document_id = recent.document_id
WHERE
updates."date" = recent."date"
) u
ON d.id = u.document_id;
Run Code Online (Sandbox Code Playgroud)
这将处理"未更新"的文档,如下所示:
pg=> select * from documents;
id | title
----+-------
1 | foo
2 | bar
3 | baz
(3 rows)
pg=> select * from updates;
id | document_id | date
----+-------------+------------
1 | 1 | 2009-10-30
2 | 1 | 2009-11-04
3 | 1 | 2009-11-07
4 | 2 | 2009-11-09
(4 rows)
pg=> SELECT d.id ...
id | title | update_id | date
----+-------+-----------+------------
1 | foo | 3 | 2009-11-07
2 | bar | 4 | 2009-11-09
3 | baz | |
(3 rows)
Run Code Online (Sandbox Code Playgroud)
select *
from documents
left join updates
on updates.document_id=documents.id
and updates.date=(select max(date) from updates where document_id=documents.id)
where documents.id=?;
Run Code Online (Sandbox Code Playgroud)
它比以前的答案有一些优点:
where documents.id in (1,2,3)。您还可以使用 group by 避免子选择,但您必须在 group by 子句中列出文档的所有字段:
select documents.*, max(date) as max_date
from documents
left join updates on documents.id=document_id
where documents.id=1
group by documents.id, title;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12035 次 |
| 最近记录: |