问题
I have a table containing Boolean values for travel modes, which looks like:
SELECT * FROM survey;
+----+-------+-------+-------+-------+
| id | bike | car | bus | metro |
+----+-------+-------+-------+-------+
| 49 | false | false | true | false |
| 51 | false | true | false | false |
| 52 | false | false | false | true |
| 53 | false | true | false | false |
+----+-------+-------+-------+-------+
Then I want select only the modes for which the value is true, so that the end result is:
+----+-------+
| id | mode |
+----+-------+
| 49 | bus |
| 51 | car |
| 52 | metro |
| 53 | car |
+----+-------+
How I achieve this please?
回答1:
You can use a case expression:
select
id,
case
when bike = true then 'bike'
when car = true then 'car'
when bus = true then 'bus'
when metro = true then 'metro'
end mode
from survey
This supposes that for each row, only one column is true. If not, only the value of the first matching column will be returned.
回答2:
You can try below way -
select id, mode from
(
select id, 'bike' as mode,bike as val from tablename
union all
select id, 'car',car from tablename
union all
select id, 'bus',bus from tablename
union all
select id, 'metro',metrofrom tablename
)A where val=true
回答3:
You can use some JSONB magic to avoid listing all columns:
select id,
(select k
from jsonb_each_text(to_jsonb(s) - 'id') as x(k,v)
where x.v = 'true') as mode
from survey s
order by id;
to_jsonb(s) - 'id' converts the whole row into a JSON value where the column name is the key and removes the id key. jsonb_each_text() then returns all values as text and picks the key where the value is true
来源:https://stackoverflow.com/questions/58591079/postgres-select-column-name-based-on-boolean-value