【问题标题】:Postgres: SELECT column name based on Boolean valuePostgres:基于布尔值选择列名
【发布时间】:2019-10-28 12:38:04
【问题描述】:

我有一个包含旅行模式布尔值的表格,如下所示:

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 |
+----+-------+-------+-------+-------+

那么我只想选择值为true的模式,这样最终的结果是:

+----+-------+
| id | mode  |
+----+-------+
| 49 | bus   |
| 51 | car   |
| 52 | metro |
| 53 | car   |
+----+-------+

请问我是怎么做到的?

【问题讨论】:

  • 如果给定行的多个列具有真值怎么办?
  • 我可以确认没有两列具有相同记录的true 值,因为调查只允许用户选择一种旅行模式。
  • 看起来像一个非常糟糕的数据模型。制作这两张表:一张用于出行方式,一张用于调查。调查表将包含一个引用相关出行模式行的列(例如 id_travelmode)。您正在查找的查询将成为两个表的单纯连接。

标签: sql postgresql select


【解决方案1】:

您可以使用case 表达式:

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

这假设对于每一行,只有一列是正确的。如果不是,则只返回第一个匹配列的值。

【讨论】:

    【解决方案2】:

    你可以试试下面的方法-

    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】:

      您可以使用一些 JSONB 魔法来避免列出所有列:

      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' 将整行转换为 JSON 值,其中列名是键并删除 id 键。 jsonb_each_text() 然后将所有值作为文本返回并选择值为true 的键

      【讨论】:

      • 啊,是的。但我认为这对于非常大的记录来说会很慢。
      • @arilwan:我没有,但你必须自己检查。但这是你必须为去规范化的数据模型付出的代价
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 2018-08-24
      • 2021-12-01
      • 2023-03-30
      相关资源
      最近更新 更多