Sha*_*vil 4 postgresql greatest-n-per-group distinct
我有一个us_customers
看起来像这样的表(有数十万行):
+----------+----------+
| id | us_state |
+----------+----------+
| 12345678 | MA |
| 23456781 | AL |
| 34567812 | GA |
| 45678123 | FL |
| 56781234 | AZ |
| 67812345 | MA |
| 78123456 | CO |
| 81234567 | FL |
+----------+----------+
Run Code Online (Sandbox Code Playgroud)
...我想n
从每个us_state
.
有没有办法在 PostgreSQL 9.3 中干净利落地做到这一点?
我可以通过以下方式us_state
轻松地从每个客户那里获得一位客户:
SELECT DISTINCT ON (us_state) id
FROM us_customers
ORDER BY us_state;
Run Code Online (Sandbox Code Playgroud)
但是,如果我想要来自每个州的三个客户,有没有一种方法可以在不多次运行相同查询的情况下做到这一点?
您可以使用窗口函数进行编号和排序id
,并且只保留第一个值:us_state
ROW_NUMBER()
n
SELECT *
FROM (
SELECT *
, ROW_NUMBER() OVER(PARTITION BY us_state ORDER BY id) as n
FROM data
) as ord
WHERE n <= 2
ORDER BY us_state
;
Run Code Online (Sandbox Code Playgroud)
或者您可以使用子查询 CROSS JOIN:
SELECT l.*
FROM (
SELECT DISTINCT us_state FROM data
) as s
CROSS JOIN LATERAL (
SELECT *
FROM data d
WHERE d.us_state = s.us_state
ORDER BY id
LIMIT 2
) as l
ORDER BY l.us_state
;
Run Code Online (Sandbox Code Playgroud)
ids
但您可以更改它并按最适合您的方式订购输出我的小样本:
id | us_state | n
123 | AL | 1
456 | AL | 2
56781234 | AZ | 1
78123456 | CO | 1
45678123 | FL | 1
81234567 | FL | 2
34567812 | GA | 1
123 | MA | 1
456 | MA | 2
Run Code Online (Sandbox Code Playgroud)
请注意, n 是 ROW_NUMBER 的结果,在第二个查询中不存在。在大表上,分区(us-state)和 order(此处为 id)列上的索引会有所帮助。
使用的样品:
CREATE TABLE data
("id" int, "us_state" varchar(2))
;
INSERT INTO data
("id", "us_state")
VALUES
(12345678, 'MA'),
(123, 'MA'),
(456, 'MA'),
(23456781, 'AL'),
(123, 'AL'),
(456, 'AL'),
(34567812, 'GA'),
(45678123, 'FL'),
(56781234, 'AZ'),
(67812345, 'MA'),
(78123456, 'CO'),
(81234567, 'FL')
;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1369 次 |
最近记录: |