【问题标题】:See if value exists in any column of every row in PostgresQL查看 PostgresQL 中每一行的任何列中是否存在值
【发布时间】:2019-05-07 20:25:05
【问题描述】:

假设我有这张表,我希望能够找到与每个 id 相关联的品牌。 请注意,这并不等同于查找每一行的值是否存在,因为单个 id 可能存在多次。 在这种情况下,我期望的结果是梅赛德斯-奔驰。

 id |    brand1     |    brand2     |    brand3
----+---------------+---------------+---------------
  1 | Mercedes-Benz |               | Fiat
  2 | Honda         |               | Mercedes-Benz
  3 | Audi          |               | Audi
  3 | Audi          |               | Mercedes-Benz
  4 | Mercedes-Benz |               | Mercedes-Benz
  5 | Mercedes-Benz | Mercedes-Benz |
  5 | Mercedes-Benz | Mercedes-Benz |
  6 | Mercedes-Benz |               | Mercedes-Benz
  7 | Mercedes-Benz | Mercedes-Benz |
  8 | Audi          |               | Audi
  8 | Audi          |               | Mercedes-Benz

我曾尝试使用EXIST,但我无法找到一种优雅的“postgresql”方式来迭代 id 列。

结果:

  |    brand      |  
  +---------------+
  | Mercedes-Benz | 

【问题讨论】:

  • 奇数桌设计。为什么是3个品牌栏目?我只会有一行,而且会有更多行。
  • 感谢您的编辑,@jarlh
  • 指定预期的结果,有那个表数据。
  • 这是描述结果。现在指定它!
  • 好的,我已经编辑了问题@jarlh

标签: sql postgresql-9.1


【解决方案1】:

取消透视数据——我建议使用横向连接——然后聚合:

select v.brand
from t cross join lateral
     (values (t.brand1), (t.brand2), (t.brand3)) v(brand)
group by brand
having count(distinct t.id) = (select count(distinct t.id) from t);

【讨论】:

    【解决方案2】:

    您可以规范化数据(如果可能,更改表结构,否则您可以运行查询以动态构建它)

    SELECT id, brand1 AS brand FROM table
    UNION
    SELECT id, brand2 FROM table
    UNION
    SELECT id, brand3 FROM table
    

    从那里,您可以使用标准聚合函数来查找您需要的信息:GROUP BY 品牌,并计算 ID 的数量

    【讨论】:

    • 这似乎也有效。哪个效率更高,这个还是使用交叉连接的那个?
    • 我不熟悉横向连接来肯定地判断,但本能地一个关键字应该比一个试图模仿它的查询更有效,所以 Gordon Linoff 的解决方案应该更好。
    猜你喜欢
    • 2021-11-06
    • 2014-07-26
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 2015-03-06
    • 2020-06-20
    相关资源
    最近更新 更多