urw*_*CFC 5 mysql sql pivot group-by query-optimization
背景:
我有看起来像这样的数据
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
Run Code Online (Sandbox Code Playgroud)
我正在尝试汇总过去 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
Run Code Online (Sandbox Code Playgroud)
关于数据:
我试过的:
这是我想出的:
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
Run Code Online (Sandbox Code Playgroud)
这实际上有效,但我可以预测对于多个来源甚至更多参数列,此查询将花费多长时间。
我一直在尝试一种叫做“过滤聚合函数(或手动数据透视) ”的东西在这里解释。但我无法理解/为我的案例实施它。
此外,我查看了数十个答案,其中大多数是每天的总和,或者是这种基本计算的复杂情况。也许我没有正确搜索它。
如您所见,我是 SQL 新手,非常感谢您的帮助。
我建议您使用 3 个不同的查询:
因为当您尝试执行全合一查询时,您最终会进行全表扫描(顺便说一句,MySQL 中CASE-WHEN-END有紧凑形式)。IF()这是非常不理想的。
如果您将其拆分为 3 个不同的查询并向该date列添加索引,那么它不会对第二个和第三个查询进行全扫描。仅适用于第一个查询,可以单独优化(例如通过缓存)。
还有这种方法:DATE_DIFF(CURRENT_DATE,date,day) <= 90
应更改为:(date >= 'date-90-days-ago'其中'date-90-days-ago'是固定日期)
因此,您不必计算每行 2 个日期的差异。您只需计算 2 个日期:30 天前和 90 天前,并将所有其他日期与这两个日期进行比较。这种方法将受益于date列索引。
| 归档时间: |
|
| 查看次数: |
1230 次 |
| 最近记录: |