2016-12-15 3 views
3

У меня есть некоторые данные в таблице radio responses Я агрегационной который выглядит следующим образом:Как найти индекс элемента в массиве JSON (PostgreSQL 9.3)?

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, но я обнаружил, что могу сделать это с idx(), если у меня есть массив int[].

Я пробовал различные решения, но все они, похоже, полагаются на ненужные данные, что кажется ненужным, особенно потому, что информация теряется в процессе (если нет чего-то, что использует WITH ORDINALITY, который я пропустил).

Я использую Postgres версии 9.3.

+0

'с т (х) (значения ('[1 , 0,0] ':: json)) выберите позицию (' 1 'в переводе (x :: текст,' [], ',' ')) из t; ' – Abelisto

+0

Это работает для этого конкретного случая, но это делает не работают в обобщенном смысле, поскольку он ищет только символ «1», а не конкретное значение. Например, если бы у меня была первая запись как '2010', тогда она вернет 3, потому что третий символ' 2010' - '1'. Не существует способа извлечь фактические данные в виде массива? –

+2

Извините, но я думаю, что у вас есть неправильный дизайн базы данных. Вы не должны использовать JSON или Array здесь, вы должны нормализовать свои таблицы. У вас даже есть дубликаты. '77 | [0,1] 77 | [0,1] 77 | [0,1] ' – e4c5

ответ

1

Ваш вопрос на самом деле не о РСУБД. Однако, если вы не хотите использовать unnesting и так далее, и если вы застряли на версии 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); 
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 | 
+-------------+---------+-----+ 
Смежные вопросы