具有基于单列数据的动态标题的 MySQL 数据透视表
我正在尝试编写一个查询来创建数据“表”,如下所示:
SELECT cs.`category_id`, cs.`ProcessDate`, cs.`PercentChange`
FROM `Category_Statistics` cs
WHERE cs.`ProcessDate` >= '2011-05-10'
AND cs.`ProcessDate` <= '2011-05-14'
它将返回类似以下内容:
CategoryId | ProcessDate | PercentChange
-------------------------------------------
category_4 | 2011-05-10 | 10
category_4 | 2011-05-11 | 18
category_4 | 2011-05012 | 12
...
category_7 | 2011-05-10 | 21
category_7 | 2011-05-11 | 7
...
category_12 | 2011-05-10 | 7
category_12 | 2011-05-11 | 15
现在我希望结果是这样的(来自 MySQL 查询,而不是由应用程序操作):
CategoryId | 2011-05-10 | 2011-05-11 | 2011-05-12 | 2011-05-13 | 2011-05-14 |
--------------------------------------------------------------------------------
category_4 | 10 | 18 | 12 | 9 | 14 |
category_7 | 21 | 7 | 16 | 14 | 13 |
categeory_12 | 7 | 15 | 11 | 19 | 8 |
--------------------------------------------------------------------------------
有两个对此的警告:
日期范围可以扩大或缩小 (取决于查询)
PercentChange 在某些情况下可能为 null 案例(假设类别_7 / 2011-05-12 可能没有设置值)
所以最终我不太确定如何构建查询的选择部分以反映动态的列数(我知道它与 CONCAT 有关)。
编辑-->部分工作代码 -->
SELECT `CategoryId`,
MAX(IF(c.`ProcessedOn` = '2011-04-20', c.`PercentChange`, NULL)) AS '2011-04-20',
MAX(IF(c.`ProcessedOn` = '2011-04-21', c.`PercentChange`, NULL)) AS '2011-04-21',
MAX(IF(c.`ProcessedOn` = '2011-04-22', c.`PercentChange`, NULL)) AS '2011-04-22',
MAX(IF(c.`ProcessedOn` = '2011-04-23', c.`PercentChange`, NULL)) AS '2011-04-23',
MAX(IF(c.`ProcessedOn` = '2011-04-24', c.`PercentChange`, NULL)) AS '2011-04-24'
FROM `Category_Gravity` c
WHERE c.`ProcessedOn` >= '2011-04-20'
AND c.`ProcessedOn` <= '2011-04-24'
GROUP BY `CategoryId`
我现在需要做的是将其
MAX(IF(c.`ProcessedOn` = '2011-04-20', c.`PercentChange`, NULL)) AS '2011-04-20',
变得更加动态(因为我的日期范围会改变)
I am trying to write a query to create a 'table' of data as follows:
SELECT cs.`category_id`, cs.`ProcessDate`, cs.`PercentChange`
FROM `Category_Statistics` cs
WHERE cs.`ProcessDate` >= '2011-05-10'
AND cs.`ProcessDate` <= '2011-05-14'
Which would return something like:
CategoryId | ProcessDate | PercentChange
-------------------------------------------
category_4 | 2011-05-10 | 10
category_4 | 2011-05-11 | 18
category_4 | 2011-05012 | 12
...
category_7 | 2011-05-10 | 21
category_7 | 2011-05-11 | 7
...
category_12 | 2011-05-10 | 7
category_12 | 2011-05-11 | 15
Now I want the results to be something like this (from a MySQL query, not manipulated by the app):
CategoryId | 2011-05-10 | 2011-05-11 | 2011-05-12 | 2011-05-13 | 2011-05-14 |
--------------------------------------------------------------------------------
category_4 | 10 | 18 | 12 | 9 | 14 |
category_7 | 21 | 7 | 16 | 14 | 13 |
categeory_12 | 7 | 15 | 11 | 19 | 8 |
--------------------------------------------------------------------------------
There are two caveats to this:
The date range can grow or shrink
(depending on the query)PercentChange may be null in some
cases (lets say category_7 /
2011-05-12 may not have a value set)
So ultimately I am not quite sure how to build the select part of the query to reflect a dynamic number of columns (I know it has something to do with CONCAT).
Edit --> Partial working code -->
SELECT `CategoryId`,
MAX(IF(c.`ProcessedOn` = '2011-04-20', c.`PercentChange`, NULL)) AS '2011-04-20',
MAX(IF(c.`ProcessedOn` = '2011-04-21', c.`PercentChange`, NULL)) AS '2011-04-21',
MAX(IF(c.`ProcessedOn` = '2011-04-22', c.`PercentChange`, NULL)) AS '2011-04-22',
MAX(IF(c.`ProcessedOn` = '2011-04-23', c.`PercentChange`, NULL)) AS '2011-04-23',
MAX(IF(c.`ProcessedOn` = '2011-04-24', c.`PercentChange`, NULL)) AS '2011-04-24'
FROM `Category_Gravity` c
WHERE c.`ProcessedOn` >= '2011-04-20'
AND c.`ProcessedOn` <= '2011-04-24'
GROUP BY `CategoryId`
What I need to do now is turn the
MAX(IF(c.`ProcessedOn` = '2011-04-20', c.`PercentChange`, NULL)) AS '2011-04-20',
into something more dynamic (as I the date ranges will change)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看一下这个类似的线程,我在其中编写了一个 sp 来完成任务
连接两个表(具有 1-M 关系),其中第二个表需要“展平”为一行
编辑。更新答案
Take a look at this similar thread where I wrote a sp to accomplish the task
Join two tables (with a 1-M relationship) where the second table needs to be 'flattened' into one row
edit. Updated answer