在子查询中聚合按位或*带分区*?

Aggregate bitwise-OR in a subquery *with partitioning*?

我一直在研究如何在子查询的 TSQL 中进行按位或聚合,popular question 中给出的答案似乎不支持分区。有什么方法可以分区吗?

假设我们有以下数据:

id | someCount | someFlags
1  | 2         | 0
1  | 3         | 2
1  | 0         | 1
2  | 1         | 4
2  | 5         | 0
2  | 1         | 1

我可以得到 someCount 字段的 SUMid 分区,而不会丢失任何原始行 ,如下所示:

SELECT [testSum] = SUM([someCount]) OVER (PARTITION BY [id]) FROM myTable

有没有办法通过按位或运算来做到这一点?所以我会得到:

id | value
1  | 3
1  | 3
1  | 3
2  | 5
2  | 5
2  | 5

试试这个:

 DECLARE @MyTable TABLE( ID int, SomeCount int, SomeFlags int)
INSERT INTO @MyTable
    VALUES
            (1, 2, 0)
        ,   (1, 3, 2)
        ,   (1, 0, 1)
        ,   (2, 1, 4)
        ,   (2, 5, 0)
        ,   (2, 1, 1)
;

WITH SumTable   AS 
    (
        SELECT 
                iD
            ,   TestSum     =   SUM(SomeCount)
            ,   BitOrSum    =   SUM(SomeCount | SomeFlags)
        FROM @MyTable
        GROUP BY ID
    )

SELECT  
        T.ID
    ,   S.TestSum
    ,   S.BitOrSum
FROM    @MyTable    T
JOIN    SumTable    S   ON  S.ID = T.ID
ORDER BY ID

一种方法如下。将其扩展到您关心的位数。

必须重复 PARTITION BY [id] 有点乏味,但我希望 SQL 服务器只进行一次分区工作并计算同一聚合运算符内的所有 MAX 表达式.

SELECT *, 
        MAX(someFlags & 1) OVER (PARTITION BY [id])  +
        MAX(someFlags & 2) OVER (PARTITION BY [id])  +
        MAX(someFlags & 4) OVER (PARTITION BY [id])  +
        MAX(someFlags & 8) OVER (PARTITION BY [id])
FROM (VALUES
(1 , 2 , 0),
(1 , 3 , 2),
(1 , 0 , 1),
(2 , 1 , 4),
(2 , 5 , 0),
(2 , 1 , 1)
)V(id ,someCount ,someFlags)