如何将聚合函数添加到不在 select 中的非分组列
How to add aggregation function to non grouped column which is not in select
我有一个 table tab
,其中包含列 a,b,c,d
。但是以下查询将不起作用,因为 c
不在 group by 子句中或缩减函数中。
SELECT a, b, c FROM tab GROUP BY a, b;
但我想要的是selectc
基于d
的最大值。我如何在 PostgreSQL 中执行此查询?
| a | b | c | d |
| 1 | 2 | 3 | 100 |
| 1 | 2 | 4 | 110 |
| 1 | 2 | 5 | 90 |
作为输出我需要第2行的结果,因为d中的值是最高的。
经典top-n-per-group
。一种方法是使用 ROW_NUMBER
:
WITH
CTE
AS
(
SELECT
a, b, c
,ROW_NUMBER() OVER(PARTITION BY a, b ORDER by d DESC) AS rn
FROM tab
)
SELECT
a, b, c
FROM CTE
WHERE rn = 1;
(a, b, d, c)
上的索引应该有所帮助。
当 table 每组只有几行并且服务器必须读取大部分 table 时,使用 ROW_NUMBER
的方法效果很好。例如,table 有 100 万行和 80 万个不同的 (a, b)
组。您必须以任何方式阅读大多数行。
如果 table 有 100 万行并且只有 20 个不同的 (a, b)
组,最好对适当的索引进行 20 次查找而不是读取所有行。
在 Postgres 中,您可以使用 distinct on
:
SELECT DISTINCT ON (a, b) a, b, c
FROM tab
ORDER BY a, b, d DESC;
此语法特定于 Postgres。它通常是执行此类操作的最有效方法。
如果你有主键,
您可以 select 在子查询中使用 max d 并在主查询中内部加入该查询。
我有一个 table tab
,其中包含列 a,b,c,d
。但是以下查询将不起作用,因为 c
不在 group by 子句中或缩减函数中。
SELECT a, b, c FROM tab GROUP BY a, b;
但我想要的是selectc
基于d
的最大值。我如何在 PostgreSQL 中执行此查询?
| a | b | c | d |
| 1 | 2 | 3 | 100 |
| 1 | 2 | 4 | 110 |
| 1 | 2 | 5 | 90 |
作为输出我需要第2行的结果,因为d中的值是最高的。
经典top-n-per-group
。一种方法是使用 ROW_NUMBER
:
WITH
CTE
AS
(
SELECT
a, b, c
,ROW_NUMBER() OVER(PARTITION BY a, b ORDER by d DESC) AS rn
FROM tab
)
SELECT
a, b, c
FROM CTE
WHERE rn = 1;
(a, b, d, c)
上的索引应该有所帮助。
当 table 每组只有几行并且服务器必须读取大部分 table 时,使用 ROW_NUMBER
的方法效果很好。例如,table 有 100 万行和 80 万个不同的 (a, b)
组。您必须以任何方式阅读大多数行。
如果 table 有 100 万行并且只有 20 个不同的 (a, b)
组,最好对适当的索引进行 20 次查找而不是读取所有行。
在 Postgres 中,您可以使用 distinct on
:
SELECT DISTINCT ON (a, b) a, b, c
FROM tab
ORDER BY a, b, d DESC;
此语法特定于 Postgres。它通常是执行此类操作的最有效方法。
如果你有主键, 您可以 select 在子查询中使用 max d 并在主查询中内部加入该查询。