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

时间:2017-10-14 16:16:04

标签: sql sql-server sql-server-2008 pivot unpivot

我有一个包含50,000条记录的数据集。格式如下所示。

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查询是什么?

4 个答案:

答案 0 :(得分:1)

您可以使用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中的工作实际上并不是很难。请记住不要依赖默认排序。

答案 1 :(得分:0)

我认为是这样的:

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

嗯......我想出了点什么。看起来它对我有用。不确定它是否效率最高。

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;