使用日期作为值的MySQL Pivot

bttbmeg0  于 2023-08-02  发布在  Mysql
关注(0)|答案(3)|浏览(114)

我尝试创建一个过程,将下表从:
| 参观|日期| Date |
| --|--| ------------ |
| 蛋糕|2023年1月1日| 01.01.2023 |
| 咖啡|2023年1月1日| 01.01.2023 |
| 蛋糕|2023年01月02日| 02.01.2023 |
| 咖啡|2023年02月02日| 02.02.2023 |
| 咖啡|2023年02月03日| 03.02.2023 |
致:
| 蛋糕|咖啡| Coffee |
| --|--| ------------ |
| 最大值(日期)2023年1月2日|最大值(日期)2023年1月1日| Max(Date) 01.01.2023 |
| 最大值(日期)无|最大值(日期)2023年2月3日| Max(Date) 03.02.2023 |
“访问”列(以及所有其他列)中不同项目的数量可以动态更改。
我注意到mysql不支持pivot,基于我在互联网上找到的,我尝试了以下方法。
不幸的是,我甚至没有让这段代码运行。你对我能改进的地方有什么想法吗?
感谢您的支持!这真是太感谢了!!
最好
珍妮
代码:

CREATE PROCEDURE VisitReport.Pivot()
BEGIN
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT(
  'MAX(CASE WHEN Visit= "', Visit, '" THEN [Date] ELSE 0 END) 
  AS ', Visit, '"')
)
INTO @sql
FROM VisitReport;
 
SET @sql = CONCAT('SELECT ID, ', @sql, 
  ' FROM VisitReport GROUP BY ID');

 
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END

字符串

2q5ifsrm

2q5ifsrm1#

我修改了Joel Coehoorn的示例,使用prepareexecute。所以没什么可复制的
请看这里:
https://dbfiddle.uk/KE6-DbTV

j0pj023g

j0pj023g2#

您可以尝试以下操作:

DELIMITER //
CREATE PROCEDURE GetCakeCoffeeDates()
BEGIN
    SELECT 
        id, 
        (CASE WHEN cakeDate IS NULL THEN 'None' ELSE cakeDate END) AS cake,
        (CASE WHEN coffeeDate IS NULL THEN 'None' ELSE coffeeDate END) AS coffee
    FROM 
        (SELECT 
            c.`id`, 
            MAX(CASE WHEN c.`visit`='Cake' THEN c.`date` END) AS cakeDate,
            MAX(CASE WHEN c.`visit`='Coffee' THEN c.`date` END) AS coffeeDate
        FROM `cake_coffee` c GROUP BY c.`id`) a;
END //
DELIMITER ;

字符串
要调用该过程,请执行以下操作:

CALL GetCakeCoffeeDates;


我只是假设除了cakecoffee之外没有其他的。
让我知道如果我错过了什么

db2dz4w8

db2dz4w83#

“访问”列(以及所有其他列)中不同项目的数量可以动态更改。
考虑到这些信息,这在单个SQL语句中是不可能做到的。
SQL语言有一个非常严格的规则,在查询编译时,在查看任何数据之前,必须知道列的数量和类型。由于您必须查看数据才能知道要显示哪些列,因此无法在单个SQL查询中完成此操作。
相反,您必须使用动态SQL分三步完成此操作:
1.运行查询以确定需要哪些列。
1.使用步骤1的结果构建一个新的SQL语句,该语句显式列出您需要的每一列
1.运行步骤2中的查询。
同样值得注意的是,添加PIVOT支持不会有帮助。即使使用PIVOT,您仍然需要知道结果列的数量。
也就是说,你已经朝着这个结果取得了很好的进展。一旦我们知道了列,PIVOT可能会改进这个查询,但是如果没有它,已经尝试过的条件聚合策略是我们最好的选择。我只需要清理一些语法问题,使用单引号而不是双引号,使用反引号而不是方括号。我还自作主张地改进了结果的格式,这有助于调试:

SELECT
    CONCAT('SELECT ID\n\t,', 
       GROUP_CONCAT(DISTINCT CONCAT(
       'MAX(CASE WHEN Visit= ''', Visit, ''' THEN `Date` END) AS ', 
       Visit, ' ') SEPARATOR  '\n\t,'),  
      '\nFROM VisitReport GROUP BY ID;') AS q
FROM VisitReport;

字符串
请看这里:
https://dbfiddle.uk/7YmQeAMf
fiddle只是将结果从第二个样本块复制/粘贴到第三个样本块,以给予正确的结果。

相关问题