在一列中具有多个属性名称而另一列中的另一行中具有多个值的行的SQL透视

时间:2018-07-11 19:57:00

标签: sql-server sql-server-2012

我有一列具有属性名格式的行,另一列具有值,例如

SourceTechAttributesName
MediaFormat, FrameRate, DropFrame, StartSmpte
MediaFormat, FrameRate, DropFrame, StartSmpte
MediaFormat, FrameRate, DropFrame, StartSmpte
MediaFormat, NativeFrameRate, ActionType, ViewportDisplayFormat, ViewportAspectRatio, FrameRate, Width, Height, ScanType, FieldDominance, DropFrame, NativeFieldOrder, CadencePattern, NumberOfAudioChannels, NumberOfAudioTracks, StartSmpte, Duration
MediaFormat, NativeFrameRate, ActionType, ViewportDisplayFormat, ViewportAspectRatio, FrameRate, Width, Height, ScanType, FieldDominance, DropFrame, NativeFieldOrder, CadencePattern, NumberOfAudioChannels, NumberOfAudioTracks, StartSmpte, Duration

并且另一列具有诸如

的值

SourceTechAttributesValue

96, 29.97, False, 00:00:00:00
96, 29.97, False, 00:00:00:00
96, 29.97, False, 00:00:00:00
645, 23.98, Live Action, Anamorphic, 1.78:1 (16x9), 23.98, 1920, 1080, Progressive, Lower Field First, False, Progressive, 2-2, 12, 12, 00:59:35:00, 1507.380875
645, 23.98, Live Action, Anamorphic, 1.78:1 (16x9), 23.98, 1920, 1080, Progressive, Lower Field First, False, Progressive, 2-2, 12, 12, 00:59:35:00, 1507.380875

我想用下面的格式介绍一下

srcMediaFormat srcFrameRate srcDropFrame srcWidth srcHeight srcCodec srcDuration
    96           29.97       FALSE              
    644          23.98       FALSE        1920     1080               1646.645
    644          23.98       FALSE        1920     1080               1626.625

我知道在该列中只有一个属性而在另一列中只有一个值(例如

)时该怎么办
pivot
(
    max(SourceTechAttributeValue)
    for SourceTechAttributeName in ([srcMediaFormat],[srcFrameRate],[srcDropFrame],[srcWidth],[srcHeight],[srcCodec],[srcDuration])

    )piv

但是由于每列都有多个attributeName和attributValue,所以我无法实现自己的目标。我希望得到如下结果

srcMediaFormat srcFrameRate srcDropFrame srcWidth srcHeight srcCodec srcDuration
        96           29.97       FALSE              
        644          23.98       FALSE        1920     1080               1646.645
        644          23.98       FALSE        1920     1080               1626.625

任何人都可以帮助我实现这一成就。谢谢

1 个答案:

答案 0 :(得分:1)

借助Parse / Split函数,该函数返回一个序列以及一个值。我们首先取消您的数据,然后执行简单的PIVOT。

我应该补充一点,用子查询替换[dbo].[tvf-Str-Parse]()是一件小事。

示例

Declare @YourTable table (ID int,SourceTechAttributesName varchar(max),SourceTechAttributesValue varchar(max))
Insert Into @YourTable values
 (1,'MediaFormat, FrameRate, DropFrame, StartSmpte','96, 29.97, False, 00:00:00:00')
,(2,'MediaFormat, NativeFrameRate, ActionType, ViewportDisplayFormat, ViewportAspectRatio, FrameRate, Width, Height, ScanType, FieldDominance, DropFrame, NativeFieldOrder, CadencePattern, NumberOfAudioChannels, NumberOfAudioTracks, StartSmpte, Duration','645, 23.98, Live Action, Anamorphic, 1.78:1 (16x9), 23.98, 1920, 1080, Progressive, Lower Field First, False, Progressive, 2-2, 12, 12, 00:59:35:00, 1507.380875')


Select *
 From  (
        Select A.ID
              ,B.*
         From  @YourTable A
         Cross Apply (Select Item  = concat('src',B1.RetVal)
                            ,Value = B2.RetVal
                       From  [dbo].[tvf-Str-Parse](SourceTechAttributesName ,',') B1
                       Join  [dbo].[tvf-Str-Parse](SourceTechAttributesValue,',') B2
                         on  B1.RetSeq=B2.RetSeq
                     ) B
       ) src
 Pivot (max(value) for Item in ([srcMediaFormat],[srcFrameRate],[srcDropFrame],[srcWidth],[srcHeight],[srcCodec],[srcDuration]) ) pvt

返回

enter image description here

为帮助可视化,子查询会生成

enter image description here

感兴趣的解析/拆分功能

CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[tvf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[tvf-Str-Parse]('this,is,<test>,for,< & >',',')