Как получить данные uniq из столбца jsonb из некоторого ключа, который содержит массив?

#postgresql

#postgresql

Вопрос:

Я использую PostgreSQL 11.9, и у меня есть столбец jsonb в моей таблице product с РАЗМЕРОМ ключа, и моя цель получить все уникальные доступные размеры во всей таблице products, как должен выглядеть запрос?

Прямо сейчас у меня есть это, но это строка для каждого продукта, я ожидал, что каждая строка будет иметь некоторый уникальный размер для всей базы данных, всех продуктов

что у меня есть

 SELECT DISTINCT sub.SIZE FROM (

SELECT
jsonb_build_object('SIZE', p.extras->'SIZE') AS SIZE
FROM products AS p
WHERE p.extras IS NOT NULL
) sub
WHERE sub.SIZE != '{"SIZE": null}';
  

и мой результат

 {"SIZE": ["32", "34", "36", "38", "52", "54", "48", "50", "40", "42", "44", "46", "32/34,36/38,52/54,48/50,40/42,44/46"]}
{"SIZE": ["38", "40", "42", "46", "48", "50", "52", "38,40,42,46,48,50,52"]}
{"SIZE": ["270", "150", "270x150cm"]}
{"SIZE": ["30", "33", "30-33"]}
{"SIZE": ["13", "5", "32", "US13.5 / EU32"]}
{"SIZE": ["3", "3 years"]}
{"SIZE": ["25", "5", "40", "25.5 / EU40"]}
{"SIZE": ["6", "23", "US6 / EU23"]}
  

этот пример содержит размер 38 в отдельной строке результата, учитывая, что это дубликат, который должен быть результатом с данными uniq. Я ожидал такого результата

 ["38", "40" .....]
  

или

  "38"
 "40"
 ...
  

это пример extra столбца из строки продукта. extra столбец имеет тип jsonb

 {"SIZE": ["3", "5", "3.5"], "COLOUR": "Vit", "CONDITION": "new", "OWN_COLOUR": "Vit"}
  

Ключ размера это массив

ОБНОВЛЕНО
РАЗРЕШЕНО

Спасибо всем, ritgh теперь два подхода для решения этого, с тем же результатом 1154 строки в результате, но в одном запросе присутствует distinct, а в другом distinct отсутствует, и тот же результат, но во всех продуктах много повторяющихся размеров, как это возможно, jsonb_array_elements сгенерированный результат uniq по умолчанию?

 select distinct x.size
from products p
cross join lateral jsonb_array_elements_text(p.extras -> 'SIZE') as x(size)

select jsonb_array_elements(p.extras -> 'SIZE') as type
from products AS p
group by type
  

Комментарии:

1. Я не понимаю, какой результат вы хотите. Массив с уникальными размерами для каждого продукта? Или просто список уникальных размеров для всех продуктов?

2. точно — уникальные размеры для всех продуктов. Я обновляю вопрос

Ответ №1:

Я думаю, вы просто хотите:

 select distinct extras ->> 'SIZE' size
from products
  

При необходимости вы можете реализовать логику фильтрации в where предложении. Может быть:

 select distinct extras ->> 'SIZE' size
from products
where extras ->> 'SIZE' is not null
  

С другой стороны, если атрибут json SIZE является массивом, то нам нужно сначала отменить его:

 select distinct x.size
from products p
cross join lateral jsonb_array_elements_text(t.extras -> 'SIZE') as x(size)
  

Комментарии:

1. нет, потому что этот запрос возвращает данные для каждого orw, но мне нужно глобально, какие данные uniq содержатся во всей базе данных

2. @shuba.ivan: select distinct выводит только уникальные значения.

3. например ["36", "38", "52", "54", "40", "42", "44", "46", "32", "34", "48", "50", "36/38,52/54,40/42,44/46,32/34,48/50"] ["2", "34", "US2 / EU34"] , мне это не нужно, «34» дублируется

4. @shuba.ivan: хорошо, похоже SIZE , это массив. Смотрите мое обновление.

5. select distinct x.size from products p cross join lateral jsonb_array_elements_text(p.extras ->> 'SIZE') as x(size) > ERROR: function jsonb_array_elements_text(text) does not exist LINE 3: cross join lateral jsonb_array_elements_text(p.extras ->> 'S... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. > Time: 0.085s