在 PostgreSQL 中,我如何 return 与值的最小值对应的整行?
In PostgreSQL how can I return the entire row that corresponds with the min of a value?
所以如果我有这样的table
id | value | detail
-------------------
12 | 20 | orange
12 | 30 | orange
13 | 16 | purple
14 | 50 | red
12 | 60 | blue
我怎样才能得到它return这个?
12 | 20 | orange
13 | 16 | purple
14 | 50 | red
如果我按 id 分组并详细说明 return 都是 12 | 20 |橙色和12 | 60 |蓝色
使用order by
和limit
:
select t.*
from table t
order by value
limit 1;
如果您在 value
上有一个索引,returns 所有匹配行的替代方法是:
select t.*
from table t
where value = (select min(value) from table t);
如果您只需要一行,则添加 limit
。
这对于窗口聚合函数来说是一项简单的任务,ROW_NUMBER:
select *
from
(
select t.*,
row_number()
over (partition by id -- for each id
order by value) as rn -- row with the minimum value
from t
) as dt
where rn = 1
Postgres 有一个 DISTINCT ON
子句来解决这种情况。使用 DISTINCT ON (id)
,查询将 return 仅为每个 id
值的第一条记录。您可以通过 ORDER BY
子句控制选择哪条记录。你的情况:
SELECT DISTINCT ON (id) *
FROM t
ORDER BY id, value
PostgreSQL 9.3 架构设置:
CREATE TABLE TEST( id INT, value INT, detail VARCHAR );
INSERT INTO TEST VALUES ( 12, 20, 'orange' );
INSERT INTO TEST VALUES ( 12, 30, 'orange' );
INSERT INTO TEST VALUES ( 13, 16, 'purple' );
INSERT INTO TEST VALUES ( 14, 50, 'red' );
INSERT INTO TEST VALUES ( 12, 60, 'blue' );
查询 1:
不确定 Redshift 是否支持这种语法:
SELECT DISTINCT
FIRST_VALUE( id ) OVER wnd AS id,
FIRST_VALUE( value ) OVER wnd AS value,
FIRST_VALUE( detail ) OVER wnd AS detail
FROM TEST
WINDOW wnd AS ( PARTITION BY id ORDER BY value )
| id | value | detail |
|----|-------|--------|
| 12 | 20 | orange |
| 14 | 50 | red |
| 13 | 16 | purple |
查询 2:
SELECT t.ID,
t.VALUE,
t.DETAIL
FROM (
SELECT *,
ROW_NUMBER() OVER ( PARTITION BY ID ORDER BY VALUE ) AS RN
FROM TEST
) t
WHERE t.RN = 1
| id | value | detail |
|----|-------|--------|
| 12 | 20 | orange |
| 13 | 16 | purple |
| 14 | 50 | red |
所以如果我有这样的table
id | value | detail
-------------------
12 | 20 | orange
12 | 30 | orange
13 | 16 | purple
14 | 50 | red
12 | 60 | blue
我怎样才能得到它return这个?
12 | 20 | orange
13 | 16 | purple
14 | 50 | red
如果我按 id 分组并详细说明 return 都是 12 | 20 |橙色和12 | 60 |蓝色
使用order by
和limit
:
select t.*
from table t
order by value
limit 1;
如果您在 value
上有一个索引,returns 所有匹配行的替代方法是:
select t.*
from table t
where value = (select min(value) from table t);
如果您只需要一行,则添加 limit
。
这对于窗口聚合函数来说是一项简单的任务,ROW_NUMBER:
select *
from
(
select t.*,
row_number()
over (partition by id -- for each id
order by value) as rn -- row with the minimum value
from t
) as dt
where rn = 1
Postgres 有一个 DISTINCT ON
子句来解决这种情况。使用 DISTINCT ON (id)
,查询将 return 仅为每个 id
值的第一条记录。您可以通过 ORDER BY
子句控制选择哪条记录。你的情况:
SELECT DISTINCT ON (id) *
FROM t
ORDER BY id, value
PostgreSQL 9.3 架构设置:
CREATE TABLE TEST( id INT, value INT, detail VARCHAR );
INSERT INTO TEST VALUES ( 12, 20, 'orange' );
INSERT INTO TEST VALUES ( 12, 30, 'orange' );
INSERT INTO TEST VALUES ( 13, 16, 'purple' );
INSERT INTO TEST VALUES ( 14, 50, 'red' );
INSERT INTO TEST VALUES ( 12, 60, 'blue' );
查询 1:
不确定 Redshift 是否支持这种语法:
SELECT DISTINCT
FIRST_VALUE( id ) OVER wnd AS id,
FIRST_VALUE( value ) OVER wnd AS value,
FIRST_VALUE( detail ) OVER wnd AS detail
FROM TEST
WINDOW wnd AS ( PARTITION BY id ORDER BY value )
| id | value | detail |
|----|-------|--------|
| 12 | 20 | orange |
| 14 | 50 | red |
| 13 | 16 | purple |
查询 2:
SELECT t.ID,
t.VALUE,
t.DETAIL
FROM (
SELECT *,
ROW_NUMBER() OVER ( PARTITION BY ID ORDER BY VALUE ) AS RN
FROM TEST
) t
WHERE t.RN = 1
| id | value | detail |
|----|-------|--------|
| 12 | 20 | orange |
| 13 | 16 | purple |
| 14 | 50 | red |