0

有一个表TABLE存储给定一天中不同时间间隔的值。一天可以分为 24 个间隔,每个间隔一个小时或 96 个间隔,每个间隔 15 分钟。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

代码

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显示时间来实现它。有没有更好的方法来做到这一点?特别是我将间隔转换为时间的部分。CASTSUBSTRING

编辑表格设计无法更改

4

3 回答 3

1

有没有更好的方法来做到这一点?

取决于你所说的更好。例如,TIME就代码量而言,以下计算表达式“更好”:

DATEADD(
  MINUTE,
  CAST(SUBSTRING([INTERVAL],4,3) AS INT) * 1440 / INTERVALCOUNT,
  CAST('00:00' AS time)
) AS [TIME]

您可能还会发现它更具可扩展性(实际上,实际上是可扩展的):如果您需要添加对半小时间隔的支持,您只需要开始使用INTERVALCOUNT = 48您的数据即可。

同时,上面的代码可能会以不太清晰的方式传达意图。因此,如果24并且96是您可能需要的唯一值INTERVALCOUNT,那么您可能不需要比您已经为您的代码部分获得的灵活性更大的灵活性。

于 2013-08-01T06:04:11.097 回答
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
于 2013-08-01T05:47:14.717 回答
0

你没有提到输出的目的是什么,但我认为它是某种报告?

我认为没有更好的方法可以做到这一点。您所拥有的是 UNPIVOT 的经典用例,并且您的解决方案对我来说似乎很合适,因为您无法更改底层数据结构。

于 2013-07-31T23:35:56.123 回答