Для битовой маски тип bitstring
будет лучшим выбором.Тогда это может выглядеть так:
SELECT BoolD::int::bit
|| BoolC::int::bit
|| BoolB::int::bit
|| BoolA::int::bit
FROM tbl;
TRUE
преобразуется в 1
, FALSE
в 0
.Вы можете просто объединить биты в цепочку битов.
Привести бит (n) к целому числу
Кажется, вам нужен integer
как результат - есть простой и быстрый способ:
SELECT (BoolD::int::bit
|| BoolC::int::bit
|| BoolB::int::bit
|| BoolA::int::bit)::bit(4)::int
FROM tbl;
Обязательно прочитайте мелкий шрифт в главе " Функции битовых строк и операторы " руководства.
Я придумал еще две идеи и собрал краткий тест / справку с 10 тыс. Строк, чтобы подвести итоги.
Настройка теста:
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
, 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
Вы также можете использовать побитовое ИЛИ |
вместо оператора +
.
Отдельные тестовые прогоны показывают в основном такую же производительность для всех пяти методов.