之后按位计算和计数设置位数

时间:2016-07-19 20:32:42

标签: ruby-on-rails postgresql activerecord

我有一张桌子:

create_table "fingerprint" do |t|
    t.bit "fp1", limit: 64
    t.bit "fp2", limit: 64
    t.bit "fp3", limit: 64
    t.bit "fp4", limit: 64
    t.bit "fp5", limit: 64
end

fp1 | fp2 | fp3 | fp4 | fp5
---------------------------
001 | 010 | 011 | 100 | 101

一个包含5个元素的数组

fp = [5,4,3,2,1]

我喜欢并按位每个元素fp的每个记录,然后计算超过5列的设置位总数。

例如:

(001 & 5) = 001
(010 & 4) = 000
(011 & 3) = 011
(100 & 2) = 000
(101 & 1) = 001
Total number of set bits: 4

我想在我的表的每一行循环这个过程。请帮我一个有效的方法(表格有大约10万行)。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

类型bit(3)的示例。您可以轻松地对bit(64)

进行调整
create table the_table (fp1 bit(3), fp2 bit(3), fp3 bit(3), fp4 bit(3), fp5 bit(3));
insert into the_table values
('001', '010', '011', '100', '101'),
('101', '011', '111', '110', '101');

with the_array(arr) as (
    values (array[5,4,3,2,1])
),
new_values as (
    select 
        fp1 & arr[1]::bit(3) n1,
        fp2 & arr[2]::bit(3) n2,
        fp3 & arr[3]::bit(3) n3,
        fp4 & arr[4]::bit(3) n4,
        fp5 & arr[5]::bit(3) n5
    from the_table
    cross join the_array
)
select 
    *, 
    length(
        translate(
            concat(n1::text, n2::text, n3::text, n4::text, n5::text),
            '0',
            '')
    ) bit_set
from new_values;

 n1  | n2  | n3  | n4  | n5  | bit_set 
-----+-----+-----+-----+-----+---------
 001 | 000 | 011 | 000 | 001 |       4
 101 | 000 | 011 | 010 | 001 |       6
(2 rows)