我有一个SQL查询(从实际使用中简化):
SELECT MIN(cola), colb FROM tbl GROUP BY colb;
但实际上,我不需要最小值 - 任何可乐值都可以 - 它仅用于显示组中的示例值。
目前PG必须完成该组,然后按可乐对每个组进行排序以找到组中的最小值,但这很慢,因为每组中有很多记录。
Postgres是否有某种FIRST(可乐)或ANY(可乐)可以返回它首先看到的任何可乐(就像你不使用聚合函数时所做的那样)或者不需要排序/读取可乐来自每一行?
答案 0 :(得分:3)
我认为使用没有订单的DISTINCT ON()
将实现您的目标:
SELECT DISTINCT ON (ColB) ColA, ColB
FROM tbl;
<强> Example on SQL Fiddle 强>
DISTINCT ON(expression [,...])仅保留给定表达式求值的每组行的第一行。使用与ORDER BY相同的规则解释DISTINCT ON表达式(参见上文)。注意&#34;第一行&#34;除非使用ORDER BY来确保首先出现所需的行,否则每个集合都是不可预测的。
但是,由于没有可用的示例数据,我无法使用MIN
或任何其他聚合函数进行比较。
答案 1 :(得分:1)
本声明:
目前,PG必须完成该组,然后用可乐对每个组进行排序 找到组中的最小值,但这很慢,因为 每组都有很多记录。
可以逻辑地描述Postgres的功能,但它并不能解释实际发生的情况。
Postgres - 与我熟悉的任何数据库一样 - 将保留最小值的“注册”。随着新数据的出现,它会将下一行的值与最小值进行比较。如果新值较小,则会将其复制。顺便提一下,min()
,max()
,avg()
和count()
都快于{{ 1}}。对于后者,必须保持组内的值列表。
count(distinct)
方法可能比distinct on
更快。但是,原因不是因为数据库引擎正在对给定group by
的所有值进行排序以获得最小值。
答案 2 :(得分:0)
尝试在sql的末尾使用fetch第一行:
http://www.postgresql.org/docs/8.1/static/sql-fetch.html
SELECT MIN(cola), colb
FROM tbl
GROUP BY colb
FETCH FIRST ROW only;
答案 3 :(得分:0)
受到Gareth的回答的启发:
; WITH C as (SELECT *, ROW_NUMBER() OVER (PARTITION BY ColB) as rn FROM tbl)
SELECT *
FROM c
WHERE rn = 1
不确定它是否会表现得比MIN()还要好。