在子查询中按位OR进行聚合

Dan*_*iel 25 t-sql sql-server sql-server-2005 aggregation

鉴于下表:

CREATE TABLE BitValues ( n int )
Run Code Online (Sandbox Code Playgroud)

是否可以计算子查询中n所有行的按位OR ?例如,如果BitValues包含这4行:

+---+
| n |
+---+
| 1 |
| 2 |
| 4 |
| 3 |
+---+

我希望子查询返回7.有没有办法在不创建UDF的情况下进行内联操作?

A-K*_*A-K 12

WITH    Bits
          AS ( SELECT   1 AS BitMask
               UNION ALL
               SELECT   2
               UNION ALL
               SELECT   4
               UNION ALL
               SELECT   8
               UNION ALL
               SELECT   16
             )
    SELECT  SUM(DISTINCT BitMask)
    FROM    ( SELECT    1 AS n
              UNION ALL
              SELECT    2
              UNION ALL
              SELECT    3
              UNION ALL
              SELECT    4
              UNION ALL
              SELECT    5
              UNION ALL
              SELECT    6
            ) AS t
            JOIN Bits ON t.n & Bits.BitMask > 0
Run Code Online (Sandbox Code Playgroud)


Zun*_*Tzu 7

一个简单的解决方案,是@ AlexKuznetsov和@Andomar的解决方案的混合体.
位掩码由递归公用表表达式生成,但比@Andomar的解决方案更简单.
然后将这些位求和,就像在@ AlexKuznetsov的解决方案中一样.
在这个例子中,我假设需要一个16位掩码,因此65536限制.您可以通过将65536更改为2 ^ N来指示N位掩码.

WITH Bits AS
(
    SELECT 1 BitMask
    UNION ALL
    SELECT 2 * BitMask FROM Bits WHERE BitMask < 65536 -- recursion
)
SELECT SUM(DISTINCT BitMask)
FROM
    (SELECT 1 n
    UNION ALL
    SELECT 2 n
    UNION ALL
    SELECT 4 n
    UNION ALL
    SELECT 3 n) t
    INNER JOIN Bits ON t.n & Bits.BitMask > 0
Run Code Online (Sandbox Code Playgroud)


小智 7

我看到这篇文章已经很老了,有一些有用的答案,但这是一种非常疯狂的直接方法...

Select  
    SUM(DISTINCT(n & 0x01)) +
    SUM(DISTINCT(n & 0x02)) +
    SUM(DISTINCT(n & 0x04))
    as OrN
From BitValues
Run Code Online (Sandbox Code Playgroud)

  • 哇!`sum(distinct)` 的实际用例。 (2认同)