【问题标题】:Aggregate bitwise-OR in a subquery *with partitioning*?在子查询中聚合按位或*分区*?
【发布时间】:2021-08-25 16:51:53
【问题描述】:

我一直在研究如何在子查询中的 TSQL 中进行按位或聚合,popular question 中给出的答案似乎并没有维护分区。有什么办法让我分区吗?

假设我们有以下数据:

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

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

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

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

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

【问题讨论】:

    标签: sql-server tsql aggregation sql-server-2019


    【解决方案1】:

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

    不得不重复 PARTITION BY [id] 有点乏味,但我希望 SQL Server 只执行一次分区工作并在同一个聚合运算符中计算所有 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)
    

    【讨论】:

      【解决方案2】:

      试试这个:

       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
      

      【讨论】:

      • 这会返回 611BitOrSum - 不是正确的 35
      • 没错。对于 ID=1:2 或 0=2; 3 或 2 = 3; 0 或 1=1。 SUM(2,3,1)=6
      • 也许您只需要 TestSum,它是 SomeCount 的简单 SUM。这是为您提供所需结果的唯一字段,但该计算中不涉及/不需要按位或。
      • 期望的结果来自分区中的所有值。 IE。选择 0|2|1, 4|0|1
      猜你喜欢
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      相关资源
      最近更新 更多