将包含多列的2行转换为包含多行的2列

时间:2014-07-15 17:10:30

标签: sql sql-server pivot

我经常在SQL Server 2005/2008中运行即席查询,我希望将多列中的两行转换为只有两列的多行。

给出这样的查询:

SELECT 
    SUM(CASE WHEN created_at IS NOT NULL THEN 1 END) AS 'TOTAL'
    , SUM(CASE WHEN created_at > '2013-07-15' THEN 1 END) AS 'CREATED W/I LAST YEAR'
    , SUM(CASE WHEN updated_at > '2013-07-15' THEN 1 END) AS 'MODIFIED W/I LAST YEAR'
    , SUM(CASE WHEN updated_at < '2011-07-15' THEN 1 END) AS 'UNTOUCHED OVER 3 YEARS'
    , SUM(CASE WHEN updated_at < '2009-07-15' THEN 1 END) AS 'UNTOUCHED OVER 5 YEARS'
    -- , often there are more columns
FROM 
    mytable
WHERE
    < filtering >

我希望它显示如下内容:

TOTAL: 5000
CREATED W/I LAST YEAR: 500
MODIFIED W/I LAST YEAR: 1500
UNTOUCHED OVER 3 YEARS: 2000
UNTOUCHED OVER 5 YEARS: 1000

我想保留DRY,而不是将一堆SELECT与UNION串在一起。我从未使用过PIVOT,UNPIVOT或CROSS APPLY。我在UNPIVOT上看到的大多数例子似乎都不适用于上面的问题 - 或者我是否必须遗漏某些内容?这似乎很简单,但“我只是没有得到它。”

1 个答案:

答案 0 :(得分:1)

;WITH t AS (
    SELECT 
        SUM(CASE WHEN created_at IS NOT NULL THEN 1 END) AS 'TOTAL'
        , SUM(CASE WHEN created_at > '2013-07-15' THEN 1 END) AS 'CREATED W/I LAST YEAR'
        , SUM(CASE WHEN updated_at > '2013-07-15' THEN 1 END) AS 'MODIFIED W/I LAST YEAR'
        , SUM(CASE WHEN updated_at < '2011-07-15' THEN 1 END) AS 'UNTOUCHED OVER 3 YEARS'
        , SUM(CASE WHEN updated_at < '2009-07-15' THEN 1 END) AS 'UNTOUCHED OVER 5 YEARS'
        -- , often there are more columns
    FROM 
        mytable
    WHERE
        < filtering >
)
SELECT name, value
FROM t
UNPIVOT(value FOR name IN (
    [TOTAL]
    , [CREATED W/I LAST YEAR]
    , [MODIFIED W/I LAST YEAR]
    , [UNTOUCHED OVER 3 YEARS]
    , [UNTOUCHED OVER 5 YEARS]
)) p