【问题标题】:How to find the index of an element within JSON array (PostgreSQL 9.3)?如何在 JSON 数组(PostgreSQL 9.3)中查找元素的索引?
【发布时间】:2016-12-15 00:47:16
【问题描述】:

我在表格radio responses 中有一些数据,我正在汇总如下所示:

SELECT question_id, arr FROM radio_responses;

  question_id |       arr       
-------------+-----------------
          73 | [1,0,0]
          73 | [1,0,0]
          73 | [0,1,0]
          73 | [0,1,0]
          73 | [0,1,0]
          73 | [0,0,1]
          73 | [0,1,0]
          73 | [0,1,0]
          73 | [0,0,1]
          73 | [0,0,1]
          73 | [1,0,0]
          74 | [1,0]
          74 | [0,1]
          74 | [1,0]
          74 | [0,1]
          74 | [1,0]
          74 | [0,1]
          77 | [0,1]
          77 | [0,1]
          77 | [0,1]

我的最终目标是从每个数组中提取1 的索引。我找不到任何使用 JSON 类型的函数,但我确实发现如果我有一个 int[] 数组,我可以使用 idx() 这样做。

我尝试了各种解决方案,但它们似乎都依赖于首先取消嵌套数据,这似乎没有必要,特别是因为在此过程中会丢失信息(除非我错过了使用 WITH ORDINALITY 的东西)。

我使用的是 Postgres 9.3 版。

【问题讨论】:

  • with t(x) as (values('[1,0,0]'::json)) select position('1' in translate(x::text,'[],','')) from t;
  • 这适用于这种特殊情况,但它不适用于一般意义上的,因为它只查找 1 字符,而不是特定值。例如,如果我的第一个条目是 2010,那么它将返回 3,因为 2010 的第三个字符是 1。没有办法将实际数据提取为数组吗?
  • 抱歉,我认为您的数据库设计完全错误。您不应该在这里使用 JSON 或 Array,您应该规范化您的表格。你甚至有重复。 77 | [0,1] 77 | [0,1] 77 | [0,1]
  • 那些是故意重复的元素,因为它们代表对问题的回答(将被计算/列表),在这种情况下,只有回答的内容及其相关的问题 ID 很重要(相关数据被存储其他地方,后来加入)。以这种格式存储它的原因是因为 JSON 可以在 Python 中非常简单地解析,而这正是服务器正在运行的。它最初嵌套在 JSON 数组的第二层,但它是通过另一个查询选择性地提取的。

标签: sql arrays json postgresql postgresql-9.3


【解决方案1】:
select      *
          ,(select min(i) + 1
            from   generate_series(0,json_array_length(arr)-1) as gs (i)
            where  (arr->>i)::int = 1
            )                           as ind

from        radio_responses
;

+-------------+---------+-----+
| question_id | arr     | ind |
+-------------+---------+-----+
| 73          | [1,0,0] | 1   |
+-------------+---------+-----+
| 73          | [1,0,0] | 1   |
+-------------+---------+-----+
| 73          | [0,1,0] | 2   |
+-------------+---------+-----+
| 73          | [0,1,0] | 2   |
+-------------+---------+-----+
| 73          | [0,1,0] | 2   |
+-------------+---------+-----+
| 73          | [0,0,1] | 3   |
+-------------+---------+-----+
| 73          | [0,1,0] | 2   |
+-------------+---------+-----+
| 73          | [0,1,0] | 2   |
+-------------+---------+-----+
| 73          | [0,0,1] | 3   |
+-------------+---------+-----+
| 73          | [0,0,1] | 3   |
+-------------+---------+-----+
| 73          | [1,0,0] | 1   |
+-------------+---------+-----+
| 74          | [1,0]   | 1   |
+-------------+---------+-----+
| 74          | [0,1]   | 2   |
+-------------+---------+-----+
| 74          | [1,0]   | 1   |
+-------------+---------+-----+
| 74          | [0,1]   | 2   |
+-------------+---------+-----+
| 74          | [1,0]   | 1   |
+-------------+---------+-----+
| 74          | [0,1]   | 2   |
+-------------+---------+-----+
| 77          | [0,1]   | 2   |
+-------------+---------+-----+
| 77          | [0,1]   | 2   |
+-------------+---------+-----+
| 77          | [0,1]   | 2   |
+-------------+---------+-----+

【讨论】:

    【解决方案2】:

    您的问题实际上与 RDBMS 无关。但是,如果您不想使用取消嵌套等,并且您坚持使用 9.3 版本:

    create or replace function json_array_position(a json, e int) returns int language plpythonu stable as $$
      import json;
      r = json.loads(a)
      return r.index(e)
    $$;
    
    select json_array_position('[1,2,3]'::json, 2);
    

    【讨论】:

      猜你喜欢
      • 2013-08-26
      • 2017-02-12
      • 2011-09-04
      • 2016-06-09
      • 2015-08-19
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多