背景:

我有看起来像这样的数据

date        src    subsrc   subsubsrc   param1  param2
2020-02-01  src1    ksjd    dfd8        47      31
2020-02-02  src1    djsk    zmnc        44      95
2020-02-03  src2    skdj    awes        92      100
2020-02-04  src2    mxsf    kajs        80      2
2020-02-05  src3    skdj    asio        46      53
2020-02-06  src3    dekl    jdqo        19      18
2020-02-07  src3    dskl    dqqq        69      18
2020-02-08  src4    sqip    riow        64      46
2020-02-09  src5    ss01    qwep        34      34

我正在尝试汇总过去30天和过去90天的所有时间(无总金额)

因此,我的最终数据将如下所示:
src     subsrc  subsubsrc   p1_all  p1_30   p1_90   p2_all  p2_30   p2_90
src1    ksjd    dfd8        7       1       7       98      7        98
src1    djsk    zmnc        0       0       0       0       0         0
src2    skdj    awes        12      12      12      4       4         4
src2    mxsf    kajs        6       6       6       31      31       31
src3    skdj    asio        0       0       0       0       0         0
src3    dekl    jdqo        20      20      20      17      17        17
src3    dskl    dqqq        3       3       3       4       4         4
src4    sqip    qwep        0       0       0       0       0         0
src5    ss01    qwes        15      15      15      2       2         2

关于数据:
  • 这只是伪数据,因此不正确。
  • 我的数据中有成千上万的行。
  • 有十几个src列组成该表的键。
  • 我必须将十几个参数列加总为30和90以及所有时间。
  • 参数列中也有空值。
  • 同一天和src列也可能有多个行。
  • 每天都会添加新数据,并且每天可能都会运行查询以获取最新的30到90的所有时间数据。

  • 我尝试过的内容:

    这是我想出的:
    SELECT src, subsubsrc, subsubsrc,
    SUM(param1) as param1_all,
    SUM(CASE WHEN DATE_DIFF(CURRENT_DATE,date,day) <= 30 THEN param1 END) as param1_30,
    SUM(CASE WHEN DATE_DIFF(CURRENT_DATE,date,day) <= 90 THEN param1 END) as param1_90,
    SUM(param2) as param2_all,
    SUM(CASE WHEN DATE_DIFF(CURRENT_DATE,date,day) <= 30 THEN param2 END) as param2_30,
    SUM(CASE WHEN DATE_DIFF(CURRENT_DATE,date,day) <= 90 THEN param2 END) as param2_90,
    FROM `MY_TABLE`
    GROUP BY src
    ORDER BY src
    

    这实际上是有效的,但我可以预料该查询将对多个源甚至更多参数列变为多长时间。

    我一直在尝试一种名为“筛选的聚合函数(或手动数据透视表)”的解释的HERE。但是我无法理解/实现它。

    我也查看了数十个答案,其中大多数是每天的总和,或者是此基本计算的复杂情况。也许我搜索不正确。

    如您所见,我是SQL的新手,非常感谢您的帮助。

    最佳答案

    您的查询看起来不错;条件聚合是透视数据集的规范方法。

    一种可能提高性能的方法是更改​​条件表达式中的日期过滤器:使用日期函数可避免使用索引。

    相反,您可以将其表达为:

    select
        src,
        subsrc,
        subsubsrc,
        sum(param1) as param1_all,
        sum(case when date >= current_date - interval 30 day then param1 end) as param1_30,
        sum(case when date >= current_date - interval 90 day then param1 end) as param1_90,
        sum(param2) as param2_all,
        sum(case when date >= current_date - interval 30 day then param2 end) as param2_30,
        sum(case when date >= current_date - interval 90 day then param2 end) as param2_90
    from my_table
    group by src, subsrc, subsubsrc
    order by src, subsrc, subsubsrc
    

    为了提高性能,以下索引可能有用:(src, subsrc, subsubsrc, date)

    请注意,我在src, subsrc, subsubsrc子句中包括了所有三个未聚合的列(group by):从MySQL 5.7开始,默认情况下这是强制性的(尽管您可以使用sql模式来改变这种行为)-大多数其他数据库都实现了相同的约束。

    关于mysql - SQL-分别汇总多个列的所有时间,30天和90天的所有时间的数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60282665/

    10-11 05:52
    查看更多