【问题标题】:Postgresql - distinct values from jsonb arrayPostgresql - 来自 jsonb 数组的不同值
【发布时间】:2017-05-25 17:39:24
【问题描述】:

我有以下 jsonb 数组列(标签)

|name | tags (jsonb)   |
--------------------------------
|john | [ "foo", "bar" ]
|smith| [ "bar", "bat" ]
|adam | [ "foo", "dot" ]

如何获取不同的标签如下 ["foo", "bar", "bat", "dot"] ?

【问题讨论】:

  • 我想你的意思是["foo", "bar", "bat", "dot"],你在这里写了两次bar
  • @fpietka 是的,感谢您指出这一点!
  • 你试过我的回答了吗
  • @e4c5,还没有......与其他一些事情联系在一起......肯定会检查并留下反馈!
  • 当您在此处发布问题时,您是在要求人们花时间阅读它,然后其中一些读者会花时间思考并写下答案。当然,您可以做的就是分配一些自己的时间来尝试这些答案??

标签: postgresql jsonb


【解决方案1】:

这将解决您的特定问题。

SELECT DISTINCT tag FROM
  (SELECT name, JSONB_ARRAY_ELEMENTS(tags) as b FROM my_table) AS foo;

但是你有一个更大的问题。像这样存储标签是一个经常重复的错误。您应该规范化您的表格。请看Django JSONField inside ArrayField

【讨论】:

  • 感谢您的建议,我已经对模型进行了规范化,并且看起来更易于使用和维护。
  • 很高兴能帮上忙
  • 仅供参考,这个答案中的规范化建议有点过时了——现在 Postgres 支持 JSONB 列上的 GIN 索引(使用疯狂的快速 ? 运算符来测试数组/键),将标签存储在 JSONB 列而不是连接表中可以帮助您避免在查询期间出现大量扇出,这是一个完全合理的解决方案。
  • 相反,Ben,您通过将逗号分隔的数据放在列中来遵循众所周知的 SQL 反模式。
【解决方案2】:

公认的解决方案有效,但可以简化:

SELECT DISTINCT JSONB_ARRAY_ELEMENTS_TEXT(tags) AS tag FROM yourtable;

此外,虽然在许多情况下这可能是一种反模式,但它仍然有有效的用途,只要您知道它的缺点(加入和搜索会更加困难)。

【讨论】:

    猜你喜欢
    • 2019-09-04
    • 2020-04-11
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多