如何在一个SQL查询中生成多个时间序列?

保罗·富内尔

这是数据库布局。我有一张桌子,每天随时间推移销售稀少。如果某物品在2015年1月1日有10笔销售,我将有一个条目,但是如果我有0个,则我没有条目。这样的事情。

|--------------------------------------|
| day_of_year | year | sales | item_id |
|--------------------------------------|
|      01     | 2015 |  20   |   A1    |
|      01     | 2015 |  11   |   A2    | 
|      07     | 2015 |  09   |   A1    | 
|     ...     | ...  |  ...  |  ...    | 
|--------------------------------------|

这就是我获得1个项目的时间序列的方式。

SELECT doy, max(sales) FROM (
    SELECT day_of_year AS doy,
           sales       AS sales
      FROM myschema.entry_daily
     WHERE item_id = theNameOfmyItem
       AND year = 2015
       AND day_of_year < 150
     UNION
    SELECT doy AS doy,
           0   AS sales
      FROM generate_series(1, 149) AS doy) as t
GROUP BY doy
ORDER BY doy;

而且我目前循环使用R对每个项目进行1个查询。然后,我将结果汇总到一个数据框中。但这很慢。我实际上只希望有一个查询,它将以以下形式聚合所有数据。

|----------------------------------------------|
| item_id | 01 | 02 | 03 | 04 | 05 | ... | 149 |
|----------------------------------------------|
|    A1   | 10 | 00 | 00 | 05 | 12 | ... |  11 |
|    A2   | 11 | 00 | 30 | 01 | 15 | ... |  09 |
|    A3   | 20 | 00 | 00 | 05 | 17 | ... |  20 |
|                       ...                    |
|----------------------------------------------|

这可能吗?顺便说一下,我正在使用Postgres数据库。

克林

解决方案1.使用聚合进行简单查询。

获得预期结果的最简单,最快的方法。sales在客户端程序中解析很容易

select item, string_agg(coalesce(sales, 0)::text, ',') sales
from (
    select distinct item_id item, doy
    from generate_series (1, 10) doy  -- change 10 to given n
    cross join entry_daily
    ) sub
left join entry_daily on item_id = item and day_of_year = doy
group by 1
order by 1;

 item |        sales         
------+----------------------
 A1   | 20,0,0,0,0,0,9,0,0,0
 A2   | 11,0,0,0,0,0,0,0,0,0
(2 rows)

解决方案2.动态创建的视图。

根据解决方案1使用array_agg()代替string_agg()该函数创建具有给定列数的视图。

create or replace function create_items_view(view_name text, days int)
returns void language plpgsql as $$
declare
    list text;
begin
    select string_agg(format('s[%s] "%s"', i::text, i::text), ',')
    into list
    from generate_series(1, days) i;

    execute(format($f$
        drop view if exists %s;
        create view %s as select item, %s
        from (
            select item, array_agg(coalesce(sales, 0)) s
            from (
                select distinct item_id item, doy
                from generate_series (1, %s) doy
                cross join entry_daily
                ) sub
            left join entry_daily on item_id = item and day_of_year = doy
            group by 1
            order by 1
        ) q
        $f$, view_name, view_name, list, days)
    );
end $$;

用法:

select create_items_view('items_view_10', 10);

select * from items_view_10;

 item | 1  | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 
------+----+---+---+---+---+---+---+---+---+----
 A1   | 20 | 0 | 0 | 0 | 0 | 0 | 9 | 0 | 0 |  0
 A2   | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  0
(2 rows)

解决方案3.交叉表。

易于使用,但由于需要定义行格式,因此对于更多的列数非常不舒服。

create extension if not exists tablefunc;

select * from crosstab (
    'select item_id, day_of_year, sales
    from entry_daily
    order by 1',
    'select i from generate_series (1, 10) i'
) as ct 
(item_id text, "1" int, "2" int, "3" int, "4" int, "5" int, "6" int, "7" int, "8" int, "9" int, "10" int);

 item_id | 1  | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 
---------+----+---+---+---+---+---+---+---+---+----
 A1      | 20 |   |   |   |   |   | 9 |   |   |   
 A2      | 11 |   |   |   |   |   |   |   |   |   
(2 rows)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在一个APK中生成多个APK

来自分类Dev

如何从sql查询结果中生成一个dynatree?

来自分类Dev

在SQL中生成一个列表

来自分类Dev

在SQL中生成一个列表

来自分类Dev

如何在R中生成时间序列数据

来自分类Dev

在R中生成一个工作日序列

来自分类Dev

如何在同一个图上一个接一个地绘制多个时间序列

来自分类Dev

如何从一个MySQL查询生成多个报告?

来自分类Dev

如何在BigQuery Standard SQL中生成序列

来自分类Dev

如何在SQL Server的一个工作日中将时间分为多个时间戳记的进出时间

来自分类Dev

解析多个文件以在gulp中生成一个文件

来自分类Dev

如何在php中生成一个永远不会重复的唯一ID

来自分类Dev

SQL:如何在一个查询(插入行)中编写多个交互式脚本

来自分类Dev

SQL查询:如何在一个表内执行多个计数比较

来自分类Dev

如何在mysql中使用一个SQL查询选择多个静态行

来自分类Dev

如何在一个查询中插入多个记录?

来自分类Dev

如何使用SQL查询在同一个表上的union all子句中生成唯一的主键值?

来自分类Dev

如何在Rust中生成一个随机数?

来自分类Dev

如何在HSQLDB中生成一个范围内的行的行列表?

来自分类Dev

如何在numpy / scipy中生成一个带1的圆的矩阵

来自分类Dev

如何在Rails中生成一个临时页面(如确认页面)?

来自分类Dev

如何在一个表达式中生成并返回结果?

来自分类Dev

如何在另一个类中生成的UIPopover中显示错误?

来自分类Dev

如何在Rails中生成一个临时页面(如确认页面)?

来自分类Dev

如何使用一个SQL查询创建多个表

来自分类Dev

如何在Swift中生成一个随机数而不重复上一个随机数?

来自分类Dev

Oracle SQL:需要生成一个查询,该查询按位置累计服务时间

来自分类Dev

如何在PostgreSQL中生成序列

来自分类Dev

如何在Presto中生成浮点序列?

Related 相关文章

  1. 1

    如何在一个APK中生成多个APK

  2. 2

    如何从sql查询结果中生成一个dynatree?

  3. 3

    在SQL中生成一个列表

  4. 4

    在SQL中生成一个列表

  5. 5

    如何在R中生成时间序列数据

  6. 6

    在R中生成一个工作日序列

  7. 7

    如何在同一个图上一个接一个地绘制多个时间序列

  8. 8

    如何从一个MySQL查询生成多个报告?

  9. 9

    如何在BigQuery Standard SQL中生成序列

  10. 10

    如何在SQL Server的一个工作日中将时间分为多个时间戳记的进出时间

  11. 11

    解析多个文件以在gulp中生成一个文件

  12. 12

    如何在php中生成一个永远不会重复的唯一ID

  13. 13

    SQL:如何在一个查询(插入行)中编写多个交互式脚本

  14. 14

    SQL查询:如何在一个表内执行多个计数比较

  15. 15

    如何在mysql中使用一个SQL查询选择多个静态行

  16. 16

    如何在一个查询中插入多个记录?

  17. 17

    如何使用SQL查询在同一个表上的union all子句中生成唯一的主键值?

  18. 18

    如何在Rust中生成一个随机数?

  19. 19

    如何在HSQLDB中生成一个范围内的行的行列表?

  20. 20

    如何在numpy / scipy中生成一个带1的圆的矩阵

  21. 21

    如何在Rails中生成一个临时页面(如确认页面)?

  22. 22

    如何在一个表达式中生成并返回结果?

  23. 23

    如何在另一个类中生成的UIPopover中显示错误?

  24. 24

    如何在Rails中生成一个临时页面(如确认页面)?

  25. 25

    如何使用一个SQL查询创建多个表

  26. 26

    如何在Swift中生成一个随机数而不重复上一个随机数?

  27. 27

    Oracle SQL:需要生成一个查询,该查询按位置累计服务时间

  28. 28

    如何在PostgreSQL中生成序列

  29. 29

    如何在Presto中生成浮点序列?

热门标签

归档