有一个表TABLE
,用于存储给定日期内各种时间间隔的值。这一天可以分为每个时间间隔24小时或每个时间间隔为15分钟的96个间隔。 TABLE
包含以下列
DATE
INTERVALCOUNT
INT001
INT002
.
.
INT096
我需要以下列格式显示表格中的值,其中基于INTERVALCOUNT
值计算时间并显示其关联值
示例输出
DATE TIME INTERVALCOUNT VALUE
2013-04-11 00:00:00.0000000 96 23.43
2013-04-11 00:15:00.0000000 96 26.91
2013-04-11 00:30:00.0000000 96 28.1999999999
2013-04-11 00:45:00.0000000 96 28.77
2013-04-23 00:00:00.0000000 24 18.3099999999
2013-04-23 01:00:00.0000000 24 20.94
CODE
SELECT [DATE],
(CASE
WHEN [INTERVALCOUNT]=96 THEN CAST(DATEADD(MINUTE,CAST(SUBSTRING([INTERVAL],4,3) AS INT)*15, [DATE]) AS Time)
WHEN [INTERVALCOUNT]=24 THEN CAST(DATEADD(HOUR,CAST(SUBSTRING([INTERVAL],4,3) AS INT), [DATE]) AS Time)
END) AS [TIME],
[INTERVALCOUNT], --24/96
[VALUE]
FROM ( SELECT [DATE],
[INTERVALCOUNT], --24/96
[INT001], [INT002], [INT003], [INT004], [INT005], [INT006], [INT007], [INT008],
[INT009], [INT010], [INT011], [INT012], [INT013], [INT014], [INT015], [INT016],
[INT017], [INT018], [INT019], [INT020], [INT021], [INT022], [INT023], [INT024],
[INT025], [INT026], [INT027], [INT028], [INT029], [INT030], [INT031], [INT032],
[INT033], [INT034], [INT035], [INT036], [INT037], [INT038], [INT039], [INT040],
[INT041], [INT042], [INT043], [INT044], [INT045], [INT046], [INT047], [INT048],
[INT049], [INT050], [INT051], [INT052], [INT053], [INT054], [INT055], [INT056],
[INT057], [INT058], [INT059], [INT060], [INT061], [INT062], [INT063], [INT064],
[INT065], [INT066], [INT067], [INT068], [INT069], [INT070], [INT071], [INT072],
[INT073], [INT074], [INT075], [INT076], [INT077], [INT078], [INT079], [INT080],
[INT081], [INT082], [INT083], [INT084], [INT085], [INT086], [INT087], [INT088],
[INT089], [INT090], [INT091], [INT092], [INT093], [INT094], [INT095], [INT096]
FROM [TABLE] ) [Source]
UNPIVOT ([VALUE] FOR [INTERVAL] IN
([INT001], [INT002], [INT003], [INT004], [INT005], [INT006], [INT007], [INT008],
[INT009], [INT010], [INT011], [INT012], [INT013], [INT014], [INT015], [INT016],
[INT017], [INT018], [INT019], [INT020], [INT021], [INT022], [INT023], [INT024],
[INT025], [INT026], [INT027], [INT028], [INT029], [INT030], [INT031], [INT032],
[INT033], [INT034], [INT035], [INT036], [INT037], [INT038], [INT039], [INT040],
[INT041], [INT042], [INT043], [INT044], [INT045], [INT046], [INT047], [INT048],
[INT049], [INT050], [INT051], [INT052], [INT053], [INT054], [INT055], [INT056],
[INT057], [INT058], [INT059], [INT060], [INT061], [INT062], [INT063], [INT064],
[INT065], [INT066], [INT067], [INT068], [INT069], [INT070], [INT071], [INT072],
[INT073], [INT074], [INT075], [INT076], [INT077], [INT078], [INT079], [INT080],
[INT081], [INT082], [INT083], [INT084], [INT085], [INT086], [INT087], [INT088],
[INT089], [INT090], [INT091], [INT092], [INT093], [INT094], [INT095], [INT096]) ) [Unpivot]
我已使用UNPIVOT
实现了该功能,并且显示时间时使用CAST
以及SUBSTRING
。有没有更好的方法呢?特别是我将时间间隔转换为时间的部分。
编辑无法更改表格设计
答案 0 :(得分:1)
有更好的方法吗?
取决于更好的含义。例如,TIME
计算的以下表达式在代码量方面“更好”:
DATEADD(
MINUTE,
CAST(SUBSTRING([INTERVAL],4,3) AS INT) * 1440 / INTERVALCOUNT,
CAST('00:00' AS time)
) AS [TIME]
您可能还发现它更具可扩展性(事实上,实际上可扩展):如果您需要添加半小时间隔的支持,您只需要开始使用{{1与您的数据。
同时,使用上述代码可以以不太清楚的方式传达意图。因此,如果INTERVALCOUNT = 48
和24
是您96
所需的唯一可能值,那么您可能不需要比您已经获得的那部分更多的灵活性代码。
答案 1 :(得分:0)
您还没有提到输出的目的是什么,但我认为它是某种报告?
我认为没有更好的方法可以做到这一点。你有什么UNPIVOT的经典用例,你的解决方案似乎适合我,因为你不能改变底层的数据结构。
答案 2 :(得分:0)
试试这个 -
DECLARE
@cols NVARCHAR(MAX)
, @SQL NVARCHAR(MAX)
SELECT @cols = STUFF((
SELECT ', [' + c.name + ']'
FROM sys.columns c
WHERE c.name LIKE 'INT%'
AND c.[object_id] = OBJECT_ID('dbo.TABLE')
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '')
SELECT @SQL = '
SELECT
[DATE]
, [TIME] = CASE
WHEN [INTERVALCOUNT] = 96
THEN CAST(DATEADD(MINUTE, CAST(SUBSTRING([INTERVAL],4,3) AS INT)*15, [DATE]) AS Time)
WHEN [INTERVALCOUNT] = 24
THEN CAST(DATEADD(HOUR, CAST(SUBSTRING([INTERVAL],4,3) AS INT), [DATE]) AS Time)
END
, [INTERVALCOUNT]
, [VALUE]
FROM (
SELECT [DATE], [INTERVALCOUNT], ' + @cols + '
FROM [TABLE]
) s
UNPIVOT ([VALUE] FOR [INTERVAL] IN (' + @cols + ') ) up
'
PRINT @SQL
EXEC sys.sp_executesql @SQL