sql - postgres 的统计模式

标签 sql postgresql statistics

我有一个具有此架构的表:

create table mytable (creation_date timestamp,
                      value int,
                      category int);

我希望每个类别每小时最多出现一个值,仅在工作日。我取得了一些进展,我现在有这样的查询:

select category,foo.h as h,value, count(value) from mytable, (
      select date_trunc('hour', 
                        '2000-01-01 00:00:00'::timestamp+generate_series(0,23)*'1 hour'::interval)::time as h) AS foo 
      where date_part('hour',creation_date) = date_part('hour',foo.h) and
            date_part('dow',creation_date) > 0 and date_part('dow',creation_date) < 6
      group by category,h,value;

结果我得到了这样的东西:

category |    h     |  value  | count 
---------+----------+---------+-------
       1 | 00:00:00 |       2 |     1
       1 | 01:00:00 |       2 |     1
       1 | 02:00:00 |       2 |     6
       1 | 03:00:00 |       2 |    31
       1 | 03:00:00 |       3 |    11
       1 | 04:00:00 |       2 |    21
       1 | 04:00:00 |       3 |     9
       1 | 13:00:00 |       1 |    14
       1 | 14:00:00 |       1 |    10
       1 | 14:00:00 |       2 |     7
       1 | 15:00:00 |       1 |    52

例如在 04:00 我必须取值 2 和 3,计数分别为 21 和 9,我只需要计数最高的值,这将是统计模式。

顺便说一句,我有超过 200 万条记录

最佳答案

这可以更简单:

SELECT DISTINCT ON (category, extract(hour FROM creation_date)::int)
       category
     , extract(hour FROM creation_date)::int AS h
     , count(*)::int AS max_ct
     , value
FROM   mytable
WHERE  extract(isodow FROM creation_date) < 6 -- no sat or sun
GROUP  BY 1,2,4
ORDER  BY 1,2,3 DESC;

基本上这些是步骤:

  1. 排除周末(WHERE ...)。使用 ISODOW来简化表达式。
  2. timestamp 中提取 hour 作为 h
  3. 类别h 分组。
  4. 计算三者组合的行数;转换为 integer - 我们不需要 bigint
  5. 类别h 和最高计数 (DESC) 排序。
  6. 只选择每个 (category, h) 对应的 category 的第一行(最高计数)。

我能够在一个查询级别执行此操作,因为 DISTINCT 在聚合函数之后 应用。

对于任何 (category, h),结果将保留 no 行,根本没有任何条目。如果您需要填写空白,LEFT JOIN 到此:

SELECT c.category, h.h
FROM   cat_tbl c
CROSS  JOIN (SELECT generate_series(0, 23) AS h) h

关于sql - postgres 的统计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9134036/

相关文章:

mysql - null 外键 mysql 不能为 null

sql - 什么时候不适合使用派生表?

date - 在 postgresql 8.3 中创建日期系列

sql - 选择用户和所有投票 SQL

mysql - VIF 在 R 中返回别名系数

python - NumPy 或 SciPy 计算加权中位数

statistics - 偏态正态分布

sql - SSD : versioning reference data with dacpac

sql - 对 3 个随机行进行采样,然后按另一个属性的字母顺序对它们进行排序

SQL - 如何从类型中选择子元素