SQL Server 2016-如何进行简单的透视

2022-08-14 00:00:00 sql sql-server sql-server-2016

我查看了许多其他示例,但它们的透视查询中总是有某种AVGSUM。我想不出该怎么把它应用到我的案例中。有很多例子,但我不能让它工作。我的查询有什么问题?

我只是想透视表(查询:SELECT LevelName, ParentNodeName from vOrgStructurePath where orgstructureid = 1545):

+---+-----------+----------------+
|   | LevelName | ParentNodeName |
+---+-----------+----------------+
| 1 | Level1    | Rough          |
+---+-----------+----------------+
| 2 | Level2    | Soft           |
+---+-----------+----------------+

至此:

+---+--------+--------+
|   | Level1 | Level2 |
+---+--------+--------+
| 1 | Rough  | Soft   |
+---+--------+--------+

这是我的尝试:

SELECT LevelName, ParentNodeName from vOrgStructurePath 
 PIVOT (LevelName for ParentNodeName IN ([Level1],[Level2])) as level
 where orgstructureid = 1545 

但它收到此错误:

Incorrect syntax near the keyword 'for'.

感谢任何帮助,谢谢!


解决方案

所有类型的透视表都需要条件聚合。这是您的RDBMS需要将多行集合为一行的唯一方法。

一些RDBMS提供特定于供应商的函数来实现透视逻辑(SQL Server是其中之一,就像Oracle一样)。但它们基本上只是基本概念之上的句法糖,这总是归结为条件聚合。

我通常反对这些特定于供应商的实现,因为它们几乎没有增加查询的复杂性,并且在可移植性(和可读性,除非您是该特定语言的专家)方面有很大损失。

这是一个透视数据的标准解决方案,即使不是所有RDBMS,也适用于大多数RDBMS:

SELECT
    MAX(CASE WHEN LevelName = 'Level1' THEN ParentNodeName END) as [Level1],
    MAX(CASE WHEN LevelName = 'Level2' THEN ParentNodeName END) as [Level2]
FROM vOrgStructurePath 
WHERE orgstructureid = 1545 

您可以轻松地将此查询过程同时处理多个orgstructureid,方法如下:

SELECT
    orgstructureid,
    MAX(CASE WHEN LevelName = 'Level1' THEN ParentNodeName END) as [Level1],
    MAX(CASE WHEN LevelName = 'Level2' THEN ParentNodeName END) as [Level2]
FROM vOrgStructurePath 
GROUP BY orgstructureid

这将为每个orgstructureid生成一条记录及其Level1Level2值。

相关文章