SQL Server:UNPIVOT查询结果如下所示?

SQL Server:UNPIVOT查询结果如下所示?

问题描述:

我有一个包含50,000条记录的数据集。格式如下所示。SQL Server:UNPIVOT查询结果如下所示?

Handle | Category | A | B | C | Misc Info 
-------|----------|-----|-----|-----|----------- 
H1  | X  | 100 | 120 | 150 | kk 
H2  | Y  | 100 | 120 | 150 | mm 
H3  | Z  | 100 | 120 | 150 | nn 

我希望查询结果看起来像下图所示。

Handle | Category | Option | Value | Misc Info 
-------|----------|--------|-------|----------- 
H1  | X  | A  | 100 | kk 
H1  |   | B  | 120 | 
H1  |   | C  | 150 | 
-------|----------|--------|-------|----------- 
H2  | Y  | A  | 100 | mm 
H2  |   | B  | 120 | 
H2  |   | C  | 150 | 
-------|----------|--------|-------|----------- 
H3  | Z  | A  | 100 | nn 
H3  |   | B  | 120 | 
H3  |   | C  | 150 | 

什么是T-SQL查询来实现此目的?

+0

这似乎是一个演示文稿问题,而不是一个SQL问题。你不能在客户端使用代码来处理这个问题吗? –

我觉得这样的事情:

SELECT Handle, Category, "A" AS Option, A as Value, Misc, Info 
UNION ALL 
SELECT Handle, Category, "B" AS Option, B as Value, Misc, Info 
UNION ALL 
SELECT Handle, Category, "C" AS Option, C as Value, Misc, Info 
ORDER BY Category 

但你需要的,如果你需要这个查询类型做Database normalization

可以使用cross apply做到这一点:

select v.handle, v.category, v.option, v.value, v.misc_info 
from t cross apply 
    (values (handle, category, 'A', a, misc_info, 1), 
      (handle, NULL, 'B', b, NULL, 2), 
      (handle, NULL, 'C', c, NULL, 3) 
    ) v(handle, category, option, value, misc_info, priority) 
order by handle, priority; 

通常情况下,这种转变在表示层最好的处理。当结果集的排序很重要时,尤其如此 - 需要order by,因为结果集是无序而没有明确的order by

(顺序是很重要的,因为categorymisc_info有时依赖于“前一个”值。)

在这种情况下,工作其实不是很难在SQL。只记得不要依靠默认排序。

您可以为此使用UNPIVOT,如下所示。

SELECT [Handle],[Category],[Option],[Value],[Misc_Info] 
FROM 
@data 
UNPIVOT 
(
    [Value] FOR [Option] IN (A,B,C) 
) AS unpivotTable; 

嗯......我想出了一些东西。看起来它对我有效。不知道它是否是最有效的。

SELECT 
    [Handle], 
    CASE [Category] 
     WHEN 'A' THEN [Category] 
     ELSE '' 
    END AS [Category], 
    [Option], 
    [Value], 
    CASE [Misc Info] 
     WHEN 'A' THEN [Misc Info] 
     ELSE '' 
    END AS [Misc Info], 
FROM (
    SELECT [Handle], [Category], [Option], [Value], [Misc Info] 
    FROM Test_Table 
    UNPIVOT 
    (
    [Value] for [Option] in ([A], [B], [C]) 
    ) as P 
) as X;