在Sql中将水平表转换为垂直表
我有以下表格格式: 我需要将此表转换为以下格式: 我在其他问题中寻找PIVOT函数,但输入表中的“键”值不是一组固定的值,它们可以是任何值。我还寻找了其他类似的问题,但我不确定在我的情况下,该如何编写查询 我的代码是:在Sql中将水平表转换为垂直表,sql,sql-server,pivot,pivot-table,Sql,Sql Server,Pivot,Pivot Table,我有以下表格格式: 我需要将此表转换为以下格式: 我在其他问题中寻找PIVOT函数,但输入表中的“键”值不是一组固定的值,它们可以是任何值。我还寻找了其他类似的问题,但我不确定在我的情况下,该如何编写查询 我的代码是: SELECT ROW_NUMBER () OVER ( ORDER BY RouteCode) AS SrNo , RouteCode AS X , SUM(Units) AS Y FROM [ INTERFACE_ok ] .[ dbo ] .[ v_A40
SELECT
ROW_NUMBER () OVER (
ORDER BY RouteCode) AS SrNo
, RouteCode AS X
, SUM(Units) AS Y
FROM
[ INTERFACE_ok ] .[ dbo ] .[ v_A40OrdersBhQt ]
WHERE [ DeliveryDate ] > CAST(
FLOOR(CAST(GETDATE () AS FLOAT)) AS DATETIME
)
AND CustomerCode LIKE '900%'
GROUP BY [ RouteCode ]
任何帮助都将不胜感激,谢谢 您正在寻找动力学枢轴
主要步骤如下
@sqlX
和@sqlY
以携带MAX
函数和CASW,当表达式创建X
和Y
枢轴列时
CONCAT
在表达式字符串和主选择字符串以及UNION ALL
@sqlX
和@sqlY
查询字符串时,将SUM函数和CASW组合起来EXECUTE
函数动态执行SQLCREATE TABLE T(
SrNo INT,
X VARCHAR(100),
Y INT
);
INSERT INTO T VALUES (1,'N1',100);
INSERT INTO T VALUES (2,'N2',200);
INSERT INTO T VALUES (3,'N3',300);
INSERT INTO T VALUES (4,'N4',400);
INSERT INTO T VALUES (5,'N5',500);
INSERT INTO T VALUES (6,'N6',600);
INSERT INTO T VALUES (7,'N7',700);
这是mysql示例
SET @sqlX = NULL;
SET @sqlY = NULL;
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(CASE WHEN SrNo =',
SrNo,
' THEN X END) '
)
) INTO @sqlX
FROM T;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(CASE WHEN SrNo =',
SrNo,
' THEN Y END) '
)
) INTO @sqlY
FROM T;
SET @sql = CONCAT('SELECT ''X'', ', @sqlX, '
FROM T
UNION ALL
SELECT ''Y'', ', @sqlY, '
FROM T
');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL Server版本
DECLARE @sqlX VARCHAR(MAX)
DECLARE @sqlY VARCHAR(MAX)
DECLARE @sql VARCHAR(MAX)
SET @sqlX = STUFF((SELECT distinct ', CAST( MAX(CASE WHEN SrNo =' + CAST(SrNo AS VARCHAR(5)) + ' THEN X END) AS VARCHAR(MAX)) '
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
SET @sqlY = STUFF((SELECT distinct ',CAST( MAX(CASE WHEN SrNo = ' + CAST(SrNo AS VARCHAR(5)) + ' THEN Y END) AS VARCHAR(MAX)) '
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set @sql = CONCAT('SELECT ''X'', ', @sqlX, '
FROM T
UNION ALL
SELECT ''Y'', ', @sqlY, '
FROM T');
execute(@sql)
结果
| X | MAX(CASE WHEN SrNo =1 THEN X END) | MAX(CASE WHEN SrNo =2 THEN X END) | MAX(CASE WHEN SrNo =3 THEN X END) | MAX(CASE WHEN SrNo =4 THEN X END) | MAX(CASE WHEN SrNo =5 THEN X END) | MAX(CASE WHEN SrNo =6 THEN X END) | MAX(CASE WHEN SrNo =7 THEN X END) |
|---|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|
| X | N1 | N2 | N3 | N4 | N5 | N6 | N7 |
| Y | 100 | 200 | 300 | 400 | 500 | 600 | 700 |
注意:
T
可以代替子查询或当前结果集。您正在查找Dynamics pivot
主要步骤如下
@sqlX
和@sqlY
以携带MAX
函数和CASW,当表达式创建X
和Y
枢轴列时
CONCAT
在表达式字符串和主选择字符串以及UNION ALL
@sqlX
和@sqlY
查询字符串时,将SUM函数和CASW组合起来EXECUTE
函数动态执行SQLCREATE TABLE T(
SrNo INT,
X VARCHAR(100),
Y INT
);
INSERT INTO T VALUES (1,'N1',100);
INSERT INTO T VALUES (2,'N2',200);
INSERT INTO T VALUES (3,'N3',300);
INSERT INTO T VALUES (4,'N4',400);
INSERT INTO T VALUES (5,'N5',500);
INSERT INTO T VALUES (6,'N6',600);
INSERT INTO T VALUES (7,'N7',700);
这是mysql示例
SET @sqlX = NULL;
SET @sqlY = NULL;
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(CASE WHEN SrNo =',
SrNo,
' THEN X END) '
)
) INTO @sqlX
FROM T;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(CASE WHEN SrNo =',
SrNo,
' THEN Y END) '
)
) INTO @sqlY
FROM T;
SET @sql = CONCAT('SELECT ''X'', ', @sqlX, '
FROM T
UNION ALL
SELECT ''Y'', ', @sqlY, '
FROM T
');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL Server版本
DECLARE @sqlX VARCHAR(MAX)
DECLARE @sqlY VARCHAR(MAX)
DECLARE @sql VARCHAR(MAX)
SET @sqlX = STUFF((SELECT distinct ', CAST( MAX(CASE WHEN SrNo =' + CAST(SrNo AS VARCHAR(5)) + ' THEN X END) AS VARCHAR(MAX)) '
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
SET @sqlY = STUFF((SELECT distinct ',CAST( MAX(CASE WHEN SrNo = ' + CAST(SrNo AS VARCHAR(5)) + ' THEN Y END) AS VARCHAR(MAX)) '
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set @sql = CONCAT('SELECT ''X'', ', @sqlX, '
FROM T
UNION ALL
SELECT ''Y'', ', @sqlY, '
FROM T');
execute(@sql)
结果
| X | MAX(CASE WHEN SrNo =1 THEN X END) | MAX(CASE WHEN SrNo =2 THEN X END) | MAX(CASE WHEN SrNo =3 THEN X END) | MAX(CASE WHEN SrNo =4 THEN X END) | MAX(CASE WHEN SrNo =5 THEN X END) | MAX(CASE WHEN SrNo =6 THEN X END) | MAX(CASE WHEN SrNo =7 THEN X END) |
|---|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|
| X | N1 | N2 | N3 | N4 | N5 | N6 | N7 |
| Y | 100 | 200 | 300 | 400 | 500 | 600 | 700 |
注意:
T
可以代替您的子查询或当前结果集。Aaron Bertrand撰写了一篇适合您需要的文章:
他的动态解决方案是在PIVOT语句中应用一个东西:
编写收集列的子查询:
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(Name)
FROM (SELECT p.Name FROM dbo.Products AS p
INNER JOIN dbo.OrderDetails AS o
ON p.ProductID = o.ProductID
GROUP BY p.Name) AS x;
然后创建可执行SQL:
SET @sql = N'
SELECT ' + STUFF(@columns, 1, 2, '') + '
FROM
(
SELECT p.Name, o.Quantity
FROM dbo.Products AS p
INNER JOIN dbo.OrderDetails AS o
ON p.ProductID = o.ProductID
) AS j
PIVOT
(
SUM(Quantity) FOR Name IN ('
+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT @sql;
最后,运行它:
EXEC sp_executesql @sql;
Aaron Bertrand写了一篇适合你需要的文章: 他的动态解决方案是在PIVOT语句中应用一个东西: 编写收集列的子查询:
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(Name)
FROM (SELECT p.Name FROM dbo.Products AS p
INNER JOIN dbo.OrderDetails AS o
ON p.ProductID = o.ProductID
GROUP BY p.Name) AS x;
然后创建可执行SQL:
SET @sql = N'
SELECT ' + STUFF(@columns, 1, 2, '') + '
FROM
(
SELECT p.Name, o.Quantity
FROM dbo.Products AS p
INNER JOIN dbo.OrderDetails AS o
ON p.ProductID = o.ProductID
) AS j
PIVOT
(
SUM(Quantity) FOR Name IN ('
+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT @sql;
最后,运行它:
EXEC sp_executesql @sql;
你的数据库管理系统是什么?mysql或sqlserver或其他?我的dbms是SqlserverOk我已经回答了你的问题,有一个sqlserver解决方案@你的数据库管理系统是什么?mysql或sqlserver或其他?我的dbms是SqlserverOk我已经回答了你的问题,有一个sqlserver解决方案@力司