如何使用 CTE 将位连接到 varbinary

How to concatenate bits to varbinary with CTE

我有一个 table,其 ID 和位的顺序如下:

ID  Bit
1   0
1   0
1   1
1   0
1   0
1   0
1   1
1   0
1   1
1   0
1   ...
... ...
2   0
2   1
2   0
2   0
2   1
2   0
2   0
2   0
2   1
2   0
2   ...
... ...
n   ...

如何使用 CTE 对 ID 列进行分组并将 Bit 列连接到 varbinary 列?

ID  Bits
1   0x...
2   0x...

提前致谢...

这应该有效...

declare @bits TABLE(ID INT, myBit BIT, Position INT);
insert into @bits values(1,0,0)
                       ,(1,0,1)
                       ,(1,1,2)
                       ,(1,0,3)
                       ,(1,0,4)
                       ,(1,0,5)
                       ,(1,1,6)
                       ,(1,0,7)
                       ,(1,1,8)
                       ,(1,0,9)

                       ,(2,0,0)
                       ,(2,1,1)
                       ,(2,0,2)
                       ,(2,0,3)
                       ,(2,1,4)
                       ,(2,0,5)
                       ,(2,0,6)
                       ,(2,0,7)
                       ,(2,1,8)
                       ,(2,0,9);
WITH myIDs AS
(
    SELECT DISTINCT ID
    FROM @bits
)
SELECT '0x' + concatenatedBits.string
FROM myIDs
CROSS APPLY
(
    SELECT
    (
    SELECT CAST(myBit AS VARCHAR(1))
    FROM @bits AS b
    WHERE b.ID=myIDs.ID
    ORDER BY Position
    FOR XML PATH(''),TYPE
    ).value('.','varchar(max)')
) AS concatenatedBits(string)
declare @Bits as Table ( Id Int, Position Int, Value Int );
insert into @Bits ( Id, Position, Value ) values
  ( 1, 0, 1 ), ( 1, 1, 1 ), ( 1, 2, 0 ), ( 1, 3, 1 ),
  ( 1, 4, 1 ), ( 1, 5, 1 ), ( 1, 6, 1 ), ( 1, 7, 0 ),
  ( 1, 8, 1 ), ( 1, 9, 0 ), ( 1, 10, 1 ), ( 1, 11, 0 ),
  ( 1, 12, 1 ), ( 1, 13, 1 ), ( 1, 14, 0 ), ( 1, 15, 1 ),
  ( 1, 16, 1 ), ( 1, 17, 0 ), ( 1, 18, 1 ), ( 1, 19, 1 ),
  ( 1, 20, 1 ), ( 1, 21, 1 ), ( 1, 22, 1 ), ( 1, 23, 0 ),
  ( 1, 24, 1 ), ( 1, 25, 1 ), ( 1, 26, 1 ), ( 1, 27, 0 ),
  ( 1, 28, 1 ), ( 1, 29, 1 ), ( 1, 30, 1 ), ( 1, 31, 1 ),
  ( 2, 0, 0 ), ( 2, 1, 1 ), ( 2, 2, 0 ), ( 2, 3, 0 ),
  ( 2, 4, 0 ), ( 2, 5, 0 ), ( 2, 6, 1 ), ( 2, 7, 0 );

select * from @Bits order by Id, Position;

with ExtendedBits as (
  select Id, Position, Value, Position / 4 as NibbleId, Power( 2, 3 - Position % 4 ) * Value as Mask
    from @Bits ),
  Nibbles as (
  select Id, NibbleId, Sum( Mask ) as Nibble
    from ExtendedBits
    group by Id, NibbleId ),
  HexStrings as (
  select Id, Stuff( ( select Substring( '0123456789ABCDEF', Nibble + 1, 1 ) from Nibbles where Id = N.Id order by NibbleId for XML Path( '' ) ), 1, 0, '' ) as HexString
    from Nibbles as N
    group by Id )
  select Id, Cast( '' as xml).value('xs:hexBinary( substring(sql:column("HexString"), 0) )', 'varbinary(max)') as VarBin
    from HexStrings;

请注意,您可以通过将最终的 SELECT 替换为 select * from ExtendedBitsNibblesHexStrings 来查看中间结果。一种方便的调试技术。