[英]PostgreSQL GROUP BY: SELECT column on MAX of another WHERE a third column = x
Let's suppose we have two tables in PostgreSQL: 假设我们在PostgreSQL中有两个表:
Table "citizens" 表“公民”
country_ref citizen_name entry_date
-----------------------------------------------------
0 peter 2013-01-14 21:00:00.000
1 fernando 2013-01-14 20:00:00.000
0 robert 2013-01-14 19:00:00.000
3 albert 2013-01-14 18:00:00.000
2 esther 2013-01-14 17:00:00.000
1 juan 2013-01-14 16:00:00.000
3 egbert 2013-01-14 15:00:00.000
1 francisco 2013-01-14 14:00:00.000
3 adolph 2013-01-14 13:00:00.000
2 emilie 2013-01-14 12:00:00.000
2 jacques 2013-01-14 11:00:00.000
0 david 2013-01-14 10:00:00.000
Table "countries" 表“国家”
country_id country_name country_group
-------------------------------------------
0 england 0
1 spain 0
2 france 1
3 germany 1
Now I want to obtain the last entered citizen on the "citizens" table for each country of a given country_group. 现在我想获得给定country_group的每个国家的“公民”表上最后输入的公民。
My best try so far is this query (Let's call it Query_1) : 到目前为止,我最好的尝试是这个查询(我们称之为Query_1):
SELECT country_ref, MAX(entry_date) FROM citizens
LEFT JOIN countries ON country_id = country_ref
WHERE country_group = 1 GROUP BY country_ref
Output: 输出:
country_ref max
---------------------------------
3 2013-01-14 18:00:00
2 2013-01-14 17:00:00
So then I could do: 那么我可以这样做:
SELECT citizen_name FROM citizens WHERE (country_ref, entry_date) IN (Query_1)
... which will give me the output I'm looking for: albert
and esther
. ...这将给我我正在寻找的输出:
albert
和esther
。
But I'd prefer to achieve this in a single query . 但我更愿意在一个查询中实现这一点。 I wonder if it's possible?
我想知道这是否可能?
This should be simplest and fastest: 这应该是最简单和最快的:
SELECT DISTINCT ON (i.country_ref)
i.citizen_name
FROM citizens i
JOIN countries o ON o.country_id = i.country_ref
WHERE o.country_group = 1
ORDER BY i.country_ref, i.entry_date DESC
You can easily return more columns from both tables by simply adding them to the SELECT
list. 只需将它们添加到
SELECT
列表中,即可轻松地从两个表中返回更多列。
SQL Fiddle. SQL小提琴。
Details, links and explanation in this related answer: 此相关答案中的详细信息,链接和说明:
SELECT citizen_name,
country_ref,
entry_date
from (
SELECT cit.citizen_name,
cit.country_ref,
MAX(cit.entry_date) over (partition by cit.country_ref) as max_date,
cit.entry_date
FROM citizens cit
LEFT JOIN countries cou ON cou.country_id = cit.country_ref
WHERE cou.country_group = 1
) t
where max_date = entry_date
SQLFiddle demo: http://www.sqlfiddle.com/#!12/50776/1 SQLFiddle演示: http ://www.sqlfiddle.com/#!12/50776/1
Why don't you simply: 你为什么不简单地说:
SELECT citizen_name FROM citizens WHERE (country_ref, entry_date) IN (
SELECT country_ref, MAX(entry_date) FROM citizens
LEFT JOIN countries ON country_id = country_ref
WHERE country_group = 1 GROUP BY country_ref
)
It might not be the best plan, but it depends on many factors, and it is simple to write. 它可能不是最好的计划,但它取决于许多因素,而且编写起来很简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.