Binary 计数';1';红移列中每个位位置的值

Binary 计数';1';红移列中每个位位置的值,binary,bit-manipulation,aggregate-functions,amazon-redshift,bitcount,Binary,Bit Manipulation,Aggregate Functions,Amazon Redshift,Bitcount,我的红移表中有一个BIGINT列,我想要一个查询: 计算此列所有行中二进制值的每个位位置出现值“1”的次数 将以一种方式显示它,我将能够采取x顶部位的位置 例如(为了简化示例,我已经将整数值写成二进制): 在这种情况下,我将能够得到前五位的位置:(3,4,6,7,2) 注意:一列最多可以有64位的位置。您可以使用位和&检查每个位置 下面是一个跨行的示例: SELECT SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) "100000

我的红移表中有一个BIGINT列,我想要一个查询:

  • 计算此列所有行中二进制值的每个位位置出现值“1”的次数
  • 将以一种方式显示它,我将能够采取x顶部位的位置
  • 例如(为了简化示例,我已经将整数值写成二进制):

    在这种情况下,我将能够得到前五位的位置:(3,4,6,7,2)


    注意:一列最多可以有64位的位置。

    您可以使用位和
    &
    检查每个位置

    下面是一个跨行的示例:

    SELECT SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) "1000000"
         , SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) "0100000"
         , SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) "0010000"
         , SUM(CASE WHEN bit_col & 8 > 0 THEN 1 ELSE 0 END)  "0001000"
         , SUM(CASE WHEN bit_col & 4 > 0 THEN 1 ELSE 0 END)  "0000100"
         , SUM(CASE WHEN bit_col & 2 > 0 THEN 1 ELSE 0 END)  "0000010"
         , SUM(CASE WHEN bit_col & 1 > 0 THEN 1 ELSE 0 END)  "0000001"
    FROM my_table
    ;
     1000000 | 0100000 | 0010000 | 0001000 | 0000100 | 0000010 | 0000001
    ---------+---------+---------+---------+---------+---------+---------
          11 |       8 |      11 |      13 |      11 |       9 |       8
    
    要在单个列中显示结果,需要使用union:

              SELECT 1 AS "col", SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 2 AS "col", SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 3 AS "col", SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 4 AS "col", SUM(CASE WHEN bit_col &  8 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 5 AS "col", SUM(CASE WHEN bit_col &  4 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 6 AS "col", SUM(CASE WHEN bit_col &  2 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 7 AS "col", SUM(CASE WHEN bit_col &  1 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    ORDER BY bit_count DESC
    ;
     position | bit_count
    ----------+-----------
            6 |         6
            7 |         6
            4 |         4
            5 |         4
            2 |         0
            3 |         0
            1 |         0
    


    编辑:如果你想要更具动态性的东西,你需要考虑使用UDF。您可以从my
    f_bitwise_to_string
    UDF开始作为模板,并从中添加所需内容

    谢谢joe,问题是,正如前面提到的,我可能会有多达64位的列,我正在寻找更具动态性的内容(因此也可以对多个列进行强制转换)。转置的联合会完成了这项工作,但在这种情况下,如果可能的话,我会寻找更具动态性的东西。如果您想要更具动态性的东西,您需要使用UDF进行研究。您可以从my
    f_bitwise_to_string
    UDF开始作为模板,并从中添加所需内容。
    SELECT SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) "1000000"
         , SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) "0100000"
         , SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) "0010000"
         , SUM(CASE WHEN bit_col & 8 > 0 THEN 1 ELSE 0 END)  "0001000"
         , SUM(CASE WHEN bit_col & 4 > 0 THEN 1 ELSE 0 END)  "0000100"
         , SUM(CASE WHEN bit_col & 2 > 0 THEN 1 ELSE 0 END)  "0000010"
         , SUM(CASE WHEN bit_col & 1 > 0 THEN 1 ELSE 0 END)  "0000001"
    FROM my_table
    ;
     1000000 | 0100000 | 0010000 | 0001000 | 0000100 | 0000010 | 0000001
    ---------+---------+---------+---------+---------+---------+---------
          11 |       8 |      11 |      13 |      11 |       9 |       8
    
              SELECT 1 AS "col", SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 2 AS "col", SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 3 AS "col", SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 4 AS "col", SUM(CASE WHEN bit_col &  8 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 5 AS "col", SUM(CASE WHEN bit_col &  4 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 6 AS "col", SUM(CASE WHEN bit_col &  2 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    UNION ALL SELECT 7 AS "col", SUM(CASE WHEN bit_col &  1 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
    ORDER BY bit_count DESC
    ;
     position | bit_count
    ----------+-----------
            6 |         6
            7 |         6
            4 |         4
            5 |         4
            2 |         0
            3 |         0
            1 |         0