我有一张桌子:
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万行)。
提前谢谢。
答案 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)