我经常在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上看到的大多数例子似乎都不适用于上面的问题 - 或者我是否必须遗漏某些内容?这似乎很简单,但“我只是没有得到它。”
答案 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