PostgreSQL统计模式值

PostgreSQL统计模式值,postgresql,statistics,Postgresql,Statistics,我正在使用SQL查询 从t中选择roundavgint_值作为模式_值; 当然,这不是正确的,而是显示某种结果的第一选择 所以,我的问题是,如何把事情做好 使用PostgreSQL 8.3+我们可以使用它来定义模式: 创建函数_final_modeanyarray以$f的形式返回任意元素$ 从最新$1 a中选择一个 按1分组按计数1说明,1 限值1; $f$语言“sql”不可变; 创建聚合modeanyelement SFUNC=array\u append,STYPE=anyarray, FI

我正在使用SQL查询

从t中选择roundavgint_值作为模式_值; 当然,这不是正确的,而是显示某种结果的第一选择

所以,我的问题是,如何把事情做好

使用PostgreSQL 8.3+我们可以使用它来定义模式:

创建函数_final_modeanyarray以$f的形式返回任意元素$ 从最新$1 a中选择一个 按1分组按计数1说明,1 限值1; $f$语言“sql”不可变; 创建聚合modeanyelement SFUNC=array\u append,STYPE=anyarray, FINALFUNC=_final_mode,INITCOND='{}' ; 但是,作为用户定义的平均值,对于大表,与buildin AVG函数比较sum/count可能会很慢。对于PostgreSQL 9+,没有用于计算统计模式值的直接内置函数?也许使用pg_统计数据。。。如何做像

从t中选择最常用的值[1]作为模式值;
该视图可以手动用于此类任务,甚至一次

您可以尝试以下方法:

SELECT int_value, count(*)
FROM t
GROUP BY int_value
ORDER BY count(*) DESC
LIMIT 1;

其背后的思想是——您获得每个int_值的计数,然后对它们进行排序,使最大的计数排在第一位,然后将查询限制为仅第一行,以获得计数最高的int_值。

如果要按组进行查询:

select
    int_value * 10 / (select max(int_value) from t) g,
    min(int_value) "from",
    max(int_value) "to",
    count(*) total
from t
group by 1
order by 4 desc

在问题介绍中,我引用了一个很好的SQL编码解决方案,@IgorRomanchenko在这个答案中使用了相同的算法@ClodoaldoNeto展示了一个新的解决方案,但正如我所评论的,这不是当前问题的答案

粘贴2个月~40个视图,无新问题

结论 结论只使用信息和证据,没有进一步的信息本页和引用的链接。总结:

用户定义的聚合模式已经足够了,我们不需要编译版本的内置

没有用于优化的基础设施,一个内置的可以做一些用户定义之外的事情

我在这样的上下文中测试了

SELECT mode(some_value) AS modal_value FROM t;
而且,在我的测试中,速度很快。。。因此,不需要像Oracle的STATS_模式这样的内置函数,只需要在统计软件包需求上下文中,但如果您愿意花费时间和内存来安装我建议的东西

另一个隐含的问题是关于一个统计包准备或使用一些PostgreSQL基础设施,如。。。一个典型答案的好线索是@IgorRomanchenko:pg_stat。。。仅包含估计值,不包含确切值。因此,正如我所想,模式功能不能利用基础设施


注意:我们必须记住,对于模式间隔,我们可以使用另一个函数,请参见@ClodoaldoNeto的答案。

模式是最有价值的,因此我sobreescrevi了我找到的函数,并做了以下操作:

CREATE OR REPLACE FUNCTION _final_mode(anyarray)
  RETURNS anyelement AS
    $BODY$
    SELECT 
        CASE 
            WHEN t1.cnt <> t2.cnt THEN t1.a 
            ELSE NULL 
        END
        FROM
            (SELECT a, COUNT(*) AS cnt
             FROM unnest($1) a
             WHERE a IS NOT NULL
             GROUP BY 1 
             ORDER BY COUNT(*) DESC, 1
             LIMIT 1
            ) as t1, 
            (SELECT a,
             COUNT(*) AS cnt
             FROM unnest($1) a
             WHERE a IS NOT NULL
             GROUP BY 1 
             ORDER BY COUNT(*) DESC, 1
             LIMIT 2 OFFSET 1
            ) as t2
    $BODY$
LANGUAGE 'sql' IMMUTABLE;

-- Tell Postgres how to use our aggregate
CREATE AGGREGATE mode(anyelement) (
  SFUNC=array_append, --Function to call for each row. Just builds the array
  STYPE=anyarray,
  FINALFUNC=_final_mode, --Function to call after everything has been added to array
  INITCOND='{}' --Initialize an empty array when starting
);

自PostgreSQL 9.4以来,有一个内置的聚合函数模式。它的用法是

SELECT mode() WITHIN GROUP (ORDER BY some_value) AS modal_value FROM tbl;
在此处阅读有关有序集聚合函数的更多信息:


有关处理旧版本的Postgres,请参阅其他答案。

pg_stat view与任何表/视图一样,处理planner统计数据只包含估计值,而不包含确切值。谢谢!好吧,我知道我对内置功能的梦想只是一个梦想。。。。它是?关于您的查询,请检查它是否与在“最终”模式函数中使用的算法不完全相同。@PeterKrauss是的,想法是相同的,只是直接应用,没有收集到数组中,也没有取消测试。谢谢@ClonaldoNeto,这是一个很好的解决方案!例如,要检测读卡器的模式间隔.PS:第一行限制1是模式;如果你改变10乘30或100,你会得到更多和微小的间隔;要列出时间间隔,请按顺序1。你好,布鲁诺。我在上面用同样的维基链接向IgorRomanchenko发布了一条评论。。。检查我们的讨论是否涵盖了您的答案以及我在上文中作为“最终”模式出现的agregate函数。问题不在于如何用SQL重现模式,而在于PostgreSQL的内置函数在何处可以快速执行此类操作。嗨@Luffydude,请检查您的PostgreSQL版本!,您可以复制/粘贴旧版本的功能。