2016-08-05 102 views
0

我有一个包含51列的CSV文件。将行转置为列SQL Server 2014

按照此顺序,每天的30分钟段(从00:30到00:00)都有一个UID列,序列列,日期列和48列。每一天都有新的一排。 所以它看起来像:

UID | Serial | Date  | Val_0030 | Val_0100 | Val_0130 | ..... | Val_0000 
123 | 123456 | 2016-01-02 | 56.2  | 23.25 | 32.8  | ..... | 86.23 

我需要这个数据转成4列,使每半小时有UID,串行和日期列。换句话说,我需要跑下来,而不是跨越。

看起来像这样:

UID | Serial | 2016-01-02 00:30 | Value 

相反,有一个新行每一天,因为它目前的确,我将决定Val_0130例如将确定时间为01:30,将与Concat的日期

我试过使用pivot和unpivot没有任何成功。任何人都可以建议最好的方法来做到这一点。

+0

您是否生成UID和串行?如果是这样,为什么你不能按照你需要的时间间隔对你的日期字段进行分组并生成它们?但是,如果UID和系列存在,他们的名字让我认为他们是独特的......你如何处理为30分钟分组选择独特的? – Kosch

+0

客户提供UID和序列号以识别设备。 UID是一个将设备定位在资产注册中的号码,序列号就是序列号。我会尝试分组,看看会发生什么。 –

+0

您需要处理每个时间间隔组的多个UID和序列组,然后 – Kosch

回答

2

我会使用UNPIVOT,然后削减列名Val_0130添加到datetime以获得所需的结果。这样你只需要在一个地方写出48列。

这里是一些测试数据:

DECLARE @Table AS TABLE (UID INT, Serial INT, Date DATETIME, Val_0030 MONEY, Val_0100 MONEY, Val_0130 MONEY, Val_0000 MONEY) 
INSERT INTO @Table (UID, Serial, Date, Val_0030, Val_0100, Val_0130, Val_0000) 
VALUES 
(123, 123456, '2016-01-02',56.2,23.25,12.34,86.23) 
,(231, 234561, '2016-01-05',26.2,13.25,23.45,106.23) 
,(312, 345612, '2016-01-07',76.2,3.25,34.56,1010.56) 

和查询

SELECT 
    UID 
    ,Serial 
    ,DateWithTime = [Date] + CAST((SUBSTRING(ColumnNames,5,2) + ':' + RIGHT(ColumnNames,2)) AS DATETIME) 
    ,Value 
FROM 
    @Table t 
    UNPIVOT (
     Value 
     FOR ColumnNames IN (Val_0030, VAL_0100, Val_0130, VAL_0000) 
    ) u 

如果你不想打字了所有48列,就像我不想,只是运行此查询并将结果复制并复制到上述查询的ColumnNames IN()部分。

DECLARE @ColString VARCHAR(MAX) = '' 
DECLARE @DT DATETIME = '00:00' 

WHILE @DT < '1900-01-02 00:00:00.000' 
BEGIN 
    IF LEN(@ColString) > 0 
    BEGIN 
     SET @ColString += ',' 
    END 

    SET @ColString += 'Val_' + FORMAT(@DT,'HHmm') 

    SET @DT = DATEADD(MINUTE,30,@DT) 
END 

SELECT @ColString 
+0

嗨马特,那工作的治疗,这是枢轴和unpivot之间的差异? –

+0

UNPIVOT是当你想取列和让他们成为行而PIVOT是为了当你想要取得行并使它们成为列而彼此相反时。在你的情况下,你有一张已经旋转的桌子,所以你想要将其转移 – Matt

1

Matt为UNPIVOT提供了一个很好的答案。在没有选项的平台上,您可以使用交叉连接和case语句获得相同的效果。创建一个半小时的表格,并生成值为

select ... 
     , case hh.time when '00:00' then VAL_0000 
         when '00:30' then Val_0030 
         when '01:00' then Val_0100 
         when '01:30' then Val_0130 
     ... 
     end as Value 
from data cross join "half-hours" as hh