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

2023-12-10

这是数据库布局。我有一张表,其中随着时间的推移销售量稀疏,每天汇总。如果某个商品在 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.动态创建视图。

基于解决方案 1array_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 $$;

Usage:

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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在一个sql查询中生成多个时间序列? 的相关文章

随机推荐

  • 更快(更具可扩展性)的DataSet.Merge?

    我们在应用程序中使用强类型数据集 导入数据时我们使用方便的DataSet Merge 将 DataRows 从一个 DataSet 复制到另一个 DataSet 的操作 StringCollection lines ReadFromFile
  • Git 将修补程序分支合并到功能分支

    假设我们在 Git 中有以下情况 创建的存储库 mkdir GitTest2 cd GitTest2 git init master 中发生一些修改并提交 echo On Master gt file git commit a m Init
  • 使用 Google Apps 脚本删除 Google 文档中的表格行

    我正在尝试使用 Google Apps 脚本使用从电子表格到 Google 的信息来大量创建文档 但我不知道如何使用 Table 类 特别是方法 RemoveRow 我创建了一个示例 不太复杂 来说明我的问题 我有一个名为 销售报告 该文档
  • JavaScript 每次调用函数时都会编译该函数吗?

    假设我有这个功能 function A function B return 1 return 1 B 是否起作用B每次调用函数时都会编译A 我记得有人说不会 但我的记忆力已经生锈了 找不到参考资料 JavaScript 标准规定 JavaS
  • 某些三星设备上的编辑文本有限?

    我正在尝试将长文本从 SD 卡读取到 Android 中的编辑文本中 在几乎所有设备上 除了某些三星设备外 此功能都运行良好 当我尝试读取超过 10kb 的任何内容时 我读取的字符串也会获取整个文件 当我尝试将其添加到编辑文本时 它在 10
  • 如何在脚本内触发大括号扩展?

    我正在编写一个需要使用 shell 的大括号扩展的脚本 但我尝试过的任何方法都不起作用 对于 人为的 实例 假设我有一个包含字符串的变量 thing 01 02 我 显然 想将其扩展到 thing01 thing02 从脚本内部 我该怎么做
  • 为什么删除 DOCTYPE 后高度 100% 仍有效?

    这是整个代码 div style background color green height 100 width 100 div 什么也没有出现 但是如果我删除第一行 doctype 所有页面如预期一样都是绿色的 我有两个问题 我该如何制作
  • UIActivityViewController 相当于 ios 5

    我正在尝试分享应用程序中的一些文本 如果用户安装了ios 6我将调用UIActivityViewController来共享 但是 如果用户有 ios 5 是否有类似的东西我可以调用 并且有按钮可以分享到邮件和 Twitter 在 ios 5
  • 什么时候需要在Python中的整数两边添加引号[重复]

    这个问题在这里已经有答案了 我刚刚了解到Python中没有整数的引号 但为什么在这种情况下需要它 character name Tom age 50 print There once was a man named character na
  • API 平台 JWT:找不到“GET /api/login”的路由

    我成功安装了 API 平台 它与我的所有实体配合良好 现在我正在尝试使用 LexikJWTAuthenticationBundle 添加 JWT 身份验证 但是当我发送登录请求时 我得到 找不到 GET api login 的路由 我的请求
  • 如何使用JS传播剩余破坏来删除嵌套属性?

    尝试使用扩展运算符剩余破坏来删除多个属性 因此药物名称被删除 但我有嵌套对象mailPrice copayEmployer那并没有被破坏 你知道什么是错误实施的吗 main js const transformedResponse tran
  • 成员函数指针和继承

    因此 为了方便起见 我正在开发一个简单的 win32 包装器 但我遇到了一个稍微复杂的问题 这还有很多其他成员 但我省略了一些 只留下有问题的成员 class Windows AbstractWindow public void Insta
  • WCF ServiceRoute 路由前缀可以包含路径值吗?

    目前我使用这个 RouteTable Routes Add new ServiceRoute API new WebServiceHostFactory typeof MySite Web MyServiceV1 使此 url 指向 MyS
  • 如何在 Pytz 中使用缩写时区名称(PST、IST)

    我需要知道如何在 pytz 上使用缩写时区名称 如 PST IST 等 的方法 现在我可以使用时区名称 例如 America Los Angeles 在时区之间进行转换 相反 我需要找到使用时区名称 如 PST IST 等 的方法 我现在用
  • GitHub Actions 中的环境和可重用工作流程

    我想找到一种方法将环境 语句从可重用工作流程移动到调用工作流程 可重用工作流程的开始是 name Reusable Terraform Action on workflow call inputs working folder descri
  • 从 javascript 提交名称值对?

    JS 可以通过 document testform submit 提交 name vale 对吗 或者是否必须通过 html 标签提交 例如
  • 如何在 Primefaces Gmap 上标记用户当前位置?

    在 Gmap 中 我们可以通过传递自定义纬度和经度来标记所需位置 有什么方法可以为用户的当前位置添加标记到地图上吗 有没有办法获取用户的纬度和经度 以前有人做过吗 请分享你的想法 您需要计算用户的 IP 地址 然后将其提供给某些 IP 地理
  • Ray 并行 python 不会改变列表

    我的问题是 如果我重新分配列表中的项目 以便重新分配发生在并行进程期间 那么在并行进程完成后 更改将恢复到其原始状态 在下面的示例中 为了便于理解而进行了极大简化 我有一个函数将列表元素 NoZeros 0 更改为 鸡 第二个函数将 NoZ
  • Codeigniter 3.x 使用表单验证登录 - 样板

    我在这里阅读了来自不同新手的几个关于 Codeigniter 中的登录和验证的问题 其中一些混合了 JavaScript 和 J query Codeigniter 本身提供了强大的表单验证以及自定义错误设置支持 我决定与您分享使用我创建的
  • 如何在一个sql查询中生成多个时间序列?

    这是数据库布局 我有一张表 其中随着时间的推移销售量稀疏 每天汇总 如果某个商品在 2015 年 1 月 1 日有 10 次销售 我将有一个条目 但如果我有 0 次销售 那么我就没有条目 像这样的东西 day of year year sa