如果非透视数据中存在不同值,为什么 SQL Server 中的透视函数会输出多行数据?

问题描述 投票:0回答:1

我正在尝试旋转表格。 有人可以解释一下为什么这会按预期工作(结果是一行数据):

;WITH My_Data AS 
(
    SELECT  
        '4A8C72D8-F02A-44E4-8E5A-23451CB436B1' AS ENTRY_UID  
        ,'Entry 1' AS ENTRY_Lang_DE
        ,'' AS ENTRY_Lang_EN

    UNION ALL 

    SELECT  
        '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E' AS ENTRY_UID  
        ,'Entry 2' AS ENTRY_Lang_DE
        ,NULL AS ENTRY_Lang_EN
)
-- SELECT * FROM My_Data 


    SELECT
        MAX(CASE WHEN ENTRY_UID = '4A8C72D8-F02A-44E4-8E5A-23451CB436B1' THEN ENTRY_Lang_DE END) AS [4A8C72D8-F02A-44E4-8E5A-23451CB436B1],
        MAX(CASE WHEN ENTRY_UID = '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E' THEN ENTRY_Lang_DE END) AS [5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E]
    FROM 
    (
        SELECT
             ENTRY_UID,
             ENTRY_Lang_DE
            ,ENTRY_Lang_EN
        FROM My_Data 
        -- WHERE ENTRY_UID <> '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E'
        -- WHERE ENTRY_UID = '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E'
        -- ORDER BY ENTRY_Lang_DE
    ) AS T_My_Data 
    ;

使用pivot关键字创建两行,一行包含NULL值,另一行是正确的输出...
为什么 ?
我的意思显然是因为 ENTRY_Lang_EN 是 NULL 而不是 string.empty,但为什么呢?
它为每个不同的 ENTRY_Lang_EN 创建一个条目?
ENTRY_Lang_EN 不受数据透视化过程的影响,为什么要这样做?
从上面的查询可以看出,结果显然不相等......

;WITH My_Data AS 
(
    SELECT  
        '4A8C72D8-F02A-44E4-8E5A-23451CB436B1' AS ENTRY_UID  
        ,'Entry 1' AS ENTRY_Lang_DE
        ,'' AS ENTRY_Lang_EN

    UNION ALL 

    SELECT  
        '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E' AS ENTRY_UID  
        ,'Entry 2' AS ENTRY_Lang_DE
        ,NULL AS ENTRY_Lang_EN
)
-- SELECT * FROM My_Data 

SELECT pvt.* FROM My_Data 

PIVOT 
( 
    MAX( ENTRY_Lang_DE ) 
    FOR ENTRY_UID IN 
    ( 
         [4A8C72D8-F02A-44E4-8E5A-23451CB436B1] 
        ,[5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E]
    ) 
) AS pvt 

不知何故,它一定在其他字段上分组,对吧?

我会想象类似的事情

;WITH My_Data AS 
(
    SELECT  
        '4A8C72D8-F02A-44E4-8E5A-23451CB436B1' AS ENTRY_UID  
        ,'Entry 1' AS ENTRY_Lang_DE
        ,'' AS ENTRY_Lang_EN

    UNION ALL 

    SELECT  
        '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E' AS ENTRY_UID  
        ,'Entry 2' AS ENTRY_Lang_DE
        ,'a' AS ENTRY_Lang_EN
)
SELECT
     CASE WHEN ENTRY_UID = '4A8C72D8-F02A-44E4-8E5A-23451CB436B1' THEN MAX(ENTRY_Lang_DE) END AS A
    ,CASE WHEN ENTRY_UID = '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E' THEN MAX(ENTRY_Lang_DE) END AS B 
FROM My_Data
GROUP BY ENTRY_UID
;

除了它按所有字段分组?
但如果是这样,那么为什么它不为每个 UID 输出一行呢?

pivot-命令在幕后到底做了什么?
或者换句话说,如果不使用pivot命令(又名带有case和max的group by)来得到这个奇怪的结果,所需的sql是什么?

sql sql-server t-sql pivot
1个回答
0
投票

要在没有枢轴的情况下获得相同的结果将需要无意义的查询,例如 ->

SELECT 
    [State],
    MAX(CASE WHEN ENTRY_UID ='4A8C72D8-F02A-44E4-8E5A-23451CB436B1' THEN ENTRY_Lang_DE ELSE NULL END) AS '4A8C72D8-F02A-44E4-8E5A-23451CB436B1',
    MAX(CASE WHEN ENTRY_UID='5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E' THEN ENTRY_Lang_DE ELSE NULL END) AS '5688ABC1-D2C5-4FE7-9E0A-6195CFF0563E'
FROM 
    My_Data 
GROUP BY
    ENTRY_Lang_EN

我认为问题在于你试图让某些东西适合一个在 SQL 语法上但在逻辑上不成立的模型。如果您要将数据重构为更容易理解的内容,那么您的输出将类似于:

状态 亚特兰大 查尔斯顿
格鲁吉亚 4000000
南卡罗来纳州 2000000
© www.soinside.com 2019 - 2024. All rights reserved.