【问题标题】:Get ANY(col) instead of MIN(col) from a group从组中获取 ANY(col) 而不是 MIN(col)
【发布时间】:2014-08-15 00:19:15
【问题描述】:

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

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

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

目前PG要先做分组,然后按cola对每个分组排序,找出分组中的最小值,但是这样很慢,因为每个分组的记录很多。

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

【问题讨论】:

    标签: sql postgresql optimization psql


    【解决方案1】:

    尝试在 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;
    

    【讨论】:

      【解决方案2】:

      我认为使用没有 order by 的 DISTINCT ON() 将实现您所追求的:

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

      Example on SQL Fiddle

      docs state

      DISTINCT ON (表达式 [, ...] ) 仅保留给定表达式计算结果为相等的每组行的第一行。 DISTINCT ON 表达式使用与 ORDER BY 相同的规则进行解释(见上文)。请注意,除非使用 ORDER BY 来确保所需的行首先出现,否则每组的“第一行”是不可预测的。

      但是,由于没有可处理的示例数据,我无法实际比较这是否会优于使用 MIN 或任何其他聚合函数。

      【讨论】:

        【解决方案3】:

        此声明:

        此刻PG要做组,然后按可乐对每组进行排序 在组中找到最小值,但这很慢,因为 每个组都有很多记录。

        可能在逻辑上描述 Postgres 做了什么,但它没有解释实际发生的事情。

        Postgres——与我熟悉的任何数据库一样——将保留一个“寄存器”以获得最小值。随着新数据的进入,它将下一行中的值与最小值进行比较。如果新值更小,那么它将被复制进来。顺便说一下,这就是为什么 min()max()avg()count() 都比 count(distinct) 快。对于后者,必须维护组内的值列表。

        distinct on 方法可能比group by 更快。然而,原因并不是因为数据库引擎正在对给定 colb 的所有值进行排序以获得最小值。

        【讨论】:

        • 确实如此。我没有想到这一点,当没有 group by 子句时肯定会发生这种情况。它是否为每个 GROUP BY colb 保留一个寄存器? IE。它是否为 colb 的每个可能值维护一个 MIN(cola) 寄存器?
        • 我认为确实如此。当我开始使用关系数据库时,这是一种古老的技术。 . .哦,我不想承认多少年前的事了。
        【解决方案4】:

        受上述 Gareth 回答的启发:

        SQL Fiddle

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

        不确定它是否会比 MIN() 执行得更好\更差。

        【讨论】:

          猜你喜欢
          • 2011-11-20
          • 2021-05-06
          • 2018-10-01
          • 2018-02-25
          • 1970-01-01
          • 2018-12-21
          • 2016-04-25
          • 2020-06-15
          • 2016-10-25
          相关资源
          最近更新 更多