Как отфильтровать некоторые записи, не вложенные в запрос

Я пытаюсь найти способ отфильтровать записи на основе запроса, но понятия не имею, как это сделать в том же операторе:

Запрос:

select unnest(array_cat(a.object_references, a.dependent_object_references)) 
from mgmt.log_metrics a

Ввод:
Select предоставит записи в следующем формате:

{а, б, г} {в, г, г} {е, л, в} {г, ч, я, е}
  • r означает стол,
  • v означает просмотр
  • f означает функцию

и на выходе мне нужно фильтровать на основе r, чтобы получить все записи таблицы. Не знаю, как этого добиться, используя приведенный выше запрос.

Выход:

{а, б, г} {в, г, г}

Я пытался применить предложение where, а также пытался поставить substring(), но после исследования обнаружил, что substring() не будет работать напрямую с unnest(). Также попробовал функцию right(), но я новичок, поэтому не знаю, как этого добиться.

Отсутствие подробностей затрудняет определение того, что вы пытаетесь сделать. Пожалуйста, просмотрите минимальный воспроизводимый пример и обновите свой пост соответствующим DDL. Не просто описывайте свои попытки, покажите реальные запросы. Абстрактные описания полезны, но конкретные примеры входных данных и желаемых результатов помогают другим понять, о чем спрашивают.

JohnH 09.07.2024 18:54

Привет @JohnH. Спасибо за ответ. Мне не нужен код, просто подсказка, например, что мне делать, чтобы отфильтровать записи, содержащие букву «r» во входных данных, должно быть хорошо. У меня нет опыта фильтрации данных из запроса unnest. если какой-либо пример или помощь будут высоко оценены.

user26309744 09.07.2024 19:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вызов табличной функции или функции, возвращающей набор , такой как unnest() в списке select, довольно распространен, но это скорее синтаксический ярлык, а не обычное место для них. Ваш код эффективно делает это:
демо на db<>fiddle

select arr.element
from mgmt.log_metrics as a
cross join lateral unnest(array_cat( a.object_references
                                    ,a.dependent_object_references)) as arr(element)

Когда вы структурируете его таким образом, становится немного яснее, что вы можете просто добавить where, чтобы отфильтровать некоторые элементы, полученные в результате unnestобъединения объединенных массивов:

select arr.element
from mgmt.log_metrics as a
cross join lateral unnest(array_cat( a.object_references
                                    ,a.dependent_object_references)) as arr(element)
where arr.element='r';

Если вы предпочитаете изменить массив перед его отменой, вы можете использовать array_remove():

select id, unnest(array_remove( array_cat( a.object_references
                                          ,a.dependent_object_references)
                               ,'r'))
from mgmt.log_metrics as a;

Если вы разбирали массив просто для доступа к отдельным элементам для выполнения поиска/фильтрации, но на выходе вам снова нужны массивы целиком, вы можете полностью удалить unnest() и использовать оператор включения @>:

select b.arr
from mgmt.log_metrics as a
cross join lateral array_cat( a.object_references
                             ,a.dependent_object_references) as b(arr)
where b.arr @> array['r'];

Если вам также необходимо учитывать положение элемента в массиве, вы можете использовать квадратные скобки [] для индексации. Обычные массивы SQL в Postgres не поддерживают отрицательные индексы для проверки последнего элемента, второго от последнего и т. д., но для достижения этого вы можете действовать относительно array_length():

select a.id, b.arr
from mgmt.log_metrics as a
cross join lateral array_cat( a.object_references
                             ,a.dependent_object_references) as b(arr)
where b.arr[array_length(b.arr,1)] = 'r';

И если вам удобно сохранять позиции или вы хотите знать их, когда вам unnest() нужно что-то еще, вы можете использовать с порядковым номером (как и в любом SRF):

select u.position, u.element
from mgmt.log_metrics as a
cross join lateral array_cat( a.object_references
                             ,a.dependent_object_references) as b(arr)
cross join lateral unnest(b.arr) WITH ORDINALITY as u(element,position)
where u.element='r' 
  and u.position=array_length(b.arr,1);

Предполагая, что ваше условие фильтра должно находиться в последнем элементе массива (... Также пробовалась функция Right...) - возможно, это поможет вам найти выход из этого:

WITH    --  S a m p l e    D a t a :
  tbl AS
    ( Select 1 as id, Array['a', 'b', '**r**'] as arr_data Union All
      Select 2 as id, Array['c', 'd', '**r**'] as arr_data Union All
      Select 3 as id, Array['e', 'l', 'v'] as arr_data Union All
      Select 4 as id, Array['g', 'h', 'i', 'f'] as arr_data 
    )
--      S Q L :
Select  t.id, t.arr_data
From    tbl t
Cross Join Lateral unnest( arr_data ) WITH ORDINALITY elem_val  
Where   ordinality = array_length( arr_data, 1 ) And   -- last element 
        elem_val = '**r**'  -- adjust this condition to your actual data and context
/*    R e s u l t :
id  arr_data
--  ----------------
 1  {a,b,**r**}
 2  {c,d,**r**}     */

См. dbfiddle здесь.

С ОБЫЧНЫМ - это стандартный синтаксис SQL, Postgres поддерживает его - нет необходимости эмулировать его с помощью оконной функции. Все элементы каждого массива имеют один и тот же e.id, поэтому конструкция sum(1), count(*) или row_number()over(Partition By e.id Order By e.id) ненадежна. Это может и в какой-то момент приведет к совершенно другому порядку по сравнению с тем, как элементы расположены на самом деле: демо. Это также немного медленнее.
Zegarek 10.07.2024 11:45

@Zegarek Ты, конечно, прав, моя ошибка. Спасибо, я обновил код.

d r 10.07.2024 12:39

Другие вопросы по теме