我希望有人可以提供帮助。这个问题最近提交给我,我认为这很容易,但(个人)认为这有点困难。我可以在Excel和SSRS中完成 - 但我很好奇我是否能够在SQL Server中完成...
我想为数据集创建一组摘要统计信息(Max,Min)。很容易......但我想将相应的日期与这些值相关联。
以下是我的数据:
我有年度数据(不完全 - 但除此之外)我使用一系列CASE WHEN语句生成这样的透视摘要。这很好 - 输出见于右侧(上图)。
每次输出这些数据时 - 我都想提供所有历史数据的摘要(为简洁起见,我只显示最新数据)。那么......问题是如何获取如下所示的输出(在不同的日期)并提供类似我右边的摘要数据集?
所以 - 一点背景。我已经设法使用UNION加入Min和Max值,这一点很好。棘手的一点(我认为)是如何形成一个INNER JOIN,使用子查询,Max或Min结果值为每个Type返回相应的Max或Min日期?现在我很有可能是一个白痴,并且遗漏了一些明显的东西....但是......真的很感激任何人的帮助......
非常感谢提前
答案 0 :(得分:1)
如果您的SQLServer是2005或更高版本,可以使用PIVOT命令,但是数据透视表的原始数据需要采用特定格式,而我提出的查询是丑陋的
WITH minmax AS (
SELECT TYPE, RESULT, [date]
, row_number() OVER (partition BY TYPE ORDER BY TYPE, RESULT) a
, row_number() OVER (partition BY TYPE ORDER BY TYPE, RESULT DESC) d
FROM t)
SELECT info
, cam = CASE charindex('date', info)
WHEN 0 THEN cast(cast(cam AS int) AS varchar(50))
ELSE cast(cam AS varchar(50))
END
, car = CASE charindex('date', info)
WHEN 0 THEN cast(cast(car AS int) AS varchar(50))
ELSE cast(cam AS varchar(50))
END
, cat = CASE charindex('date', info)
WHEN 0 THEN cast(cast(cat AS int) AS varchar(50))
ELSE cast(cam AS varchar(50))
END
FROM (SELECT TYPE, 'maxres' info, RESULT value FROM minmax WHERE 1 = d
UNION ALL
SELECT TYPE, 'minres' info, RESULT value FROM minmax WHERE 1 = a
UNION ALL
SELECT TYPE, 'maxdate' info , [date] value FROM minmax WHERE 1 = d
UNION ALL
SELECT TYPE, 'mindate' info , [date] value FROM minmax WHERE 1 = a) DATA
PIVOT
(max(value) FOR TYPE IN ([CAM], [CAR], [CAT])) pvt
它只是一个概念证明所以SQLFiddle我使用了一组减少的假数据(每3类3行)
数据准备后
SELECT TYPE, 'maxres' info, RESULT value FROM minmax WHERE 1 = d
UNION ALL
SELECT TYPE, 'minres' info, RESULT value FROM minmax WHERE 1 = a
UNION ALL
SELECT TYPE, 'maxdate' info , [date] value FROM minmax WHERE 1 = d
UNION ALL
SELECT TYPE, 'mindate' info , [date] value FROM minmax WHERE 1 = a
value列被隐式地转换为更复杂的数据类型,在这种情况下是DateTime(在同一列中不能有不同的数据类型),以预期的方式查看数据需要显式转换,并且已完成
中的CASE和CAST, cam = CASE charindex('date', info)
WHEN 0 THEN cast(cast(cam AS int) AS varchar(50))
ELSE cast(cam AS varchar(50))
END
CASE检查数据类型,查找子字符串' date'在info列中,然后将行值转换回INT为minres和maxres列,并且在任何情况下将值转换为varchar(50)以再次具有相同的数据类型
<强>更新强>
使用sql_variant,不需要CASE CAST块,谢谢Ryx5
WITH minmax AS (
SELECT TYPE, RESULT, [date]
, row_number() OVER (partition BY TYPE ORDER BY TYPE, RESULT) a
, row_number() OVER (partition BY TYPE ORDER BY TYPE, RESULT DESC) d
FROM table_name)
SELECT info
, [CAM], [CAR], [CAT]
FROM (SELECT TYPE, 'maxres' info, cast(RESULT as sql_variant) value
FROM minmax WHERE 1 = d
UNION ALL
SELECT TYPE, 'minres' info, cast(RESULT as sql_variant) value
FROM minmax WHERE 1 = a
UNION ALL
SELECT TYPE, 'maxdate' info , cast([date] as sql_variant) value
FROM minmax WHERE 1 = d
UNION ALL
SELECT TYPE, 'mindate' info , cast([date] as sql_variant) value
FROM minmax WHERE 1 = a) DATA
PIVOT
(max(value) FOR TYPE IN ([CAM], [CAR], [CAT])) pvt
答案 1 :(得分:1)
此查询将完成此任务,并适用于所有TYPE
SELECT
Description, [CAR], [CAT], [MAT], [EAT], [PAR], [MAR], [FAR], [MOT], [LOT], [COT], [ROT]
FROM
(SELECT
unpvt.TYPE
,unpvt.Description
,unpvt.value
FROM (
SELECT
t.TYPE
,CONVERT(sql_variant,MAX(maxResult.MAX_RESULT)) as MAX_RESULT
,CONVERT(sql_variant,MIN(minResult.MIN_RESULT)) as MIN_RESULT
,CONVERT(sql_variant,MAX(CASE WHEN maxResult.MAX_RESULT IS NOT NULL THEN t.DATE ELSE NULL END)) as MAX_DATE
,CONVERT(sql_variant,MIN(CASE WHEN minResult.MIN_RESULT IS NOT NULL THEN t.DATE ELSE NULL END)) as MIN_DATE
FROM
table_name t -- You need to set your table name
LEFT JOIN (SELECT
TYPE
,MIN(RESULT) as MIN_RESULT
FROM
table_name -- You need to set your table name
GROUP BY
TYPE) minResult
on minResult.TYPE = t.TYPE
and minResult.MIN_RESULT = t.RESULT
LEFT JOIN (SELECT
TYPE
,MAX(RESULT) as MAX_RESULT
FROM
table_name -- You need to set your table name
GROUP BY
TYPE) maxResult
on maxResult.TYPE = t.TYPE
and maxResult.MAX_RESULT = t.RESULT
GROUP BY
t.TYPE) U
unpivot (
value
for Description in (MAX_RESULT, MIN_RESULT, MAX_DATE, MIN_DATE)
) unpvt) P
PIVOT
(
MAX(value)
FOR TYPE IN ([CAR], [CAT], [MAT], [EAT], [PAR], [MAR], [FAR], [MOT], [LOT], [COT], [ROT])
)AS PVT
DEMO: SQLFIDDLE
CONVERT(sql_variant,
是针对公共数据类型的列的强制转换。当您使用子查询FROM
运行时,这是UNPIVOT运算符的要求。