从组中获取ANY(col)而不是MIN(col)

时间:2014-06-24 16:22:15

标签: sql postgresql optimization psql

我有一个SQL查询(从实际使用中简化):

SELECT MIN(cola), colb FROM tbl GROUP BY colb;

但实际上,我不需要最小值 - 任何可乐值都可以 - 它仅用于显示组中的示例值。

目前PG必须完成该组,然后按可乐对每个组进行排序以找到组中的最小值,但这很慢,因为每组中有很多记录。

Postgres是否有某种FIRST(可乐)或ANY(可乐)可以返回它首先看到的任何可乐(就像你不使用聚合函数时所做的那样)或者不需要排序/读取可乐来自每一行?

4 个答案:

答案 0 :(得分:3)

我认为使用没有订单的DISTINCT ON()将实现您的目标:

SELECT DISTINCT ON (ColB) ColA, ColB
FROM tbl;

<强> Example on SQL Fiddle

docs state

  

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的回答的启发:

SQL Fiddle

; WITH C as (SELECT *, ROW_NUMBER() OVER (PARTITION BY ColB) as rn FROM tbl)
SELECT *
FROM c
WHERE rn = 1

不确定它是否会表现得比MIN()还要好。

相关问题