PostgreSQL如何将行值设为列标题实现数据透视?
实现SQL行转列(将日期行转为列标题)
你需要的是**行转列(Pivot)**效果,把ValuationDate的不同取值转为列名,同时聚合每个PlatformProductId在对应日期的销量。下面分不同场景给出解决方案:
一、静态日期范围(日期固定,如你示例中的12.01-12.03)
这种情况直接用CASE配合GROUP BY即可,所有数据库通用:
SELECT PlatformProductId, -- 对应12月1日的销量,无数据则显示0 COALESCE(SUM(CASE WHEN ValuationDate = '2023-12-01' THEN TotalQuantitySold END), 0) AS '01-12-2023', -- 对应12月2日的销量 COALESCE(SUM(CASE WHEN ValuationDate = '2023-12-02' THEN TotalQuantitySold END), 0) AS '02-12-2023', -- 对应12月3日的销量 COALESCE(SUM(CASE WHEN ValuationDate = '2023-12-03' THEN TotalQuantitySold END), 0) AS '03-12-2023' FROM TableA WHERE ValuationDate BETWEEN '2023-12-01' AND '2023-12-03' GROUP BY PlatformProductId;
说明:
CASE语句筛选出对应日期的销量,SUM聚合该产品在当天的总销量;COALESCE用于把无数据的NULL转为0,若希望保留NULL可去掉该函数;- 列名的日期格式(如
01-12-2023)可根据需求用日期函数调整,比如MySQL用DATE_FORMAT,SQL Server用FORMAT。
二、专用数据库的PIVOT语法(更简洁)
如果使用支持PIVOT语法的数据库(如SQL Server、Oracle),可以用更简洁的写法:
SQL Server示例:
SELECT PlatformProductId, [2023-12-01] AS '01-12-2023', [2023-12-02] AS '02-12-2023', [2023-12-03] AS '03-12-2023' FROM ( -- 子查询获取原始数据 SELECT ValuationDate, TotalQuantitySold, PlatformProductId FROM TableA WHERE ValuationDate BETWEEN '2023-12-01' AND '2023-12-03' ) AS SourceData PIVOT ( -- 聚合方式:求和销量 SUM(TotalQuantitySold) -- 要转成列的字段:ValuationDate FOR ValuationDate IN ([2023-12-01], [2023-12-02], [2023-12-03]) ) AS PivotResult;
三、动态日期范围(日期不固定,自动生成列)
如果你的日期范围经常变化,不想每次手动写列名,可以用动态SQL自动生成列:
MySQL示例(8.0+):
-- 生成动态SQL语句 SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'COALESCE(SUM(CASE WHEN ValuationDate = ''', ValuationDate, ''' THEN TotalQuantitySold END), 0) AS ''', DATE_FORMAT(ValuationDate, '%d-%m-%Y'), '''' ) ) INTO @sql FROM TableA WHERE ValuationDate BETWEEN '2023-12-01' AND '2023-12-03'; -- 拼接完整查询语句 SET @sql = CONCAT('SELECT PlatformProductId, ', @sql, ' FROM TableA WHERE ValuationDate BETWEEN ''2023-12-01'' AND ''2023-12-03'' GROUP BY PlatformProductId'); -- 执行动态SQL PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
说明:
- 动态SQL会自动遍历指定日期范围内的所有日期,生成对应的列;
DATE_FORMAT(ValuationDate, '%d-%m-%Y')用于把数据库中的日期格式转为你需要的DD-MM-YYYY格式作为列名。
内容的提问来源于stack exchange,提问作者Shishank
相关产品推荐
相关产品推荐

