我的遗留数据库包含一个包含多个boolean类型列的表。 E.g:
TABLE_1
id name has_lights has_engine has_brakes has_tyres can_move
1 bullock_cart false false false true true
2 car true true true true true
3 tank true true true false true
我想为Table1编写一个SQL查询来获取id和name以及属性(由列名称表示)为true。
预期输出:
id name attributes
-- ---- ----------
1 bullock_cart has_tyres
1 bullock_cart can_move
2 car has_lights
2 car has_engine
2 car has_brakes
2 car has_tyres
2 car can_move
3 tank has_lights
3 tank has_engine
3 tank has_brakes
3 tank can_move
我写道:
SELECT id, name,
CASE
WHEN has_lights THEN 'has_lights'
WHEN has_engine THEN 'has_engine'
WHEN has_brakes THEN 'has_brakes'
WHEN has_tyres THEN 'has_tyres'
WHEN can_move THEN 'can_move'
END
FROM TABLE1;
但这只得到Table1中每一行的第一个匹配属性(凭CASE-WHEN)。
以我想要的格式检索数据的正确方法是什么?任何输入/帮助将不胜感激?
注意:
答案 0 :(得分:4)
最简单的方法是union all
:
select id, name, 'has_lights' as attribute from t where has_lights union all
select id, name, 'has_engine' from t where has_engine union all
select id, name, 'has_brakes' from t where has_brakes union all
select id, name, 'has_tyres' from t where has_tyres union all
select id, name, 'can_move' from t where can_move;
如果你有一个非常大的表,那么横向连接可能更有效:
select t.id, t.name, v.attribute
from t, lateral
(select attribute
from (values (has_lights, 'has_lights'),
(has_engine, 'has_engine'),
(has_brakes, 'has_brakes'),
(has_tyres, 'has_tyres'),
(can_move, 'can_move')
) v(flag, attribute)
where flag
) v;
答案 1 :(得分:2)
您可以使用UNION ALL
执行此操作:
SELECT name,'has_lights' as attributes FROM YourTable where has_lights = 'TRUE'
UNION ALL
SELECT name,'has_engine' as attributes FROM YourTable where has_engine= 'TRUE'
UNION ALL
SELECT name,'has_brakes' as attributes FROM YourTable where has_brakes = 'TRUE'
UNION ALL
SELECT name,'has_tyres' as attributes FROM YourTable where has_tyres = 'TRUE'
UNION ALL
SELECT name,'can_move' as attributes FROM YourTable where can_move = 'TRUE'
答案 2 :(得分:1)
这就像精彩的查询@Gordon posted:
SELECT t.id, t.name, v.attribute
FROM table1 t
JOIN LATERAL (
VALUES (has_lights, 'has_lights')
, (has_engine, 'has_engine')
, (has_brakes, 'has_brakes')
, (has_tyres , 'has_tyres')
, (can_move , 'can_move')
) v(flag, attribute) ON v.flag;
因为VALUES
表达式可以独立存在,所以会缩短一点。