我想转换一个查询,例如:
SELECT BoolA,BoolB,BoolC,BoolD FROM MyTable;
进入位掩码,其中位由上面的值定义.
例如,如果BoolA和BoolD是真的,我想要1001或9.
我有一些想法的效果:
SELECT CASE WHEN BoolD THEN 2^0 ELSE 0 END + CASE WHEN BoolC THEN 2^1 ELSE 0 END + CASE WHEN BoolB THEN 2^2 ELSE 0 END + CASE WHEN BoolA THEN 2^3 ELSE 0 END FROM MyTable;
但我不确定这是否是最好的方法,而且看起来相当冗长.是否有捷径可寻?
对于位掩码,类型
bitstring
将是更好的选择.可能看起来像这样:
SELECT BoolD::int::bit || BoolC::int::bit || BoolB::int::bit || BoolA::int::bit FROM tbl;
TRUE转换为1,FALSE为0.您可以简单地将位连接到位串.
将位(n)转换为整数
看起来你需要一个整数 – 有一个简单的&快捷方式:
SELECT (BoolD::int::bit || BoolC::int::bit || BoolB::int::bit || BoolA::int::bit)::bit(4)::int FROM tbl;
请务必阅读本手册“Bit String Functions and Operators”一章中的细则.
我提出了两个更多的想法,并组装了一个快速测试/参考与10k行总结.
测试设置:
CREATE TEMP TABLE t (boola bool,boolb bool,boolc bool,boold bool); INSERT INTO t SELECT random()::int::bool,random()::int::bool,random()::int::bool FROM generate_series(1,10000);
演示:
SELECT CASE WHEN boold THEN 1 ELSE 0 END + (CASE WHEN boolc THEN 1 ELSE 0 END << 1) + (CASE WHEN boolb THEN 1 ELSE 0 END << 2) + (CASE WHEN boola THEN 1 ELSE 0 END << 3) AS andriy,boold::int + (boolc::int << 1) + (boolb::int << 2) + (boola::int << 3) AS mike,(boola::int::bit || boolb::int::bit || boolc::int::bit || boold::int::bit)::bit(4)::int AS erwin1,boold::int | (boolc::int << 1) | (boolb::int << 2) | (boola::int << 3) AS erwin2,((( boola::int << 1) | boolb::int << 1) | boolc::int << 1) | boold::int AS erwin3 FROM t LIMIT 15