LISTAGG в разделе WHERE

Мне нужен запрос вроде

select id,name from sample
where 
(:test IS NULL
 OR name IN (:test))
)

Это возможно? Я не хочу использовать внутренние запросы.

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

Tim Biegeleisen 11.12.2018 06:49

Я хочу отфильтровать запрос, используя параметр запроса: тест, который представляет собой значения, разделенные запятыми. Например, у меня есть столбец имен со значениями ex1, ex2, ex3. Мне нужно получить все идентификаторы и имена из таблицы, где имена находятся в ('ex1', 'ex2'). Итак, на выходе будут две строки с именами ex1 и ex2.

Allen 11.12.2018 07:09

независимо от того, имеет ли: test значение null или имя в (: test), он выдаст все строки !!!

nikhil sugandh 11.12.2018 08:21
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
331
3

Ответы 3

Попробуйте этот запрос:

SELECT id, name
FROM sample
WHERE :test LIKE CONCAT('%,', CONCAT(name, ',%'));

вы не можете использовать listagg в IN, потому что для сопоставления требуется результирующий набор только одного столбца, который не будет работать. попробуйте простой:

select id,name from sample
where :test is null or
:test  in (select name from sample);

из предложения where вашего, похоже, вам понадобится только все идентификаторы, имена из таблицы. независимо от того, имеет ли: test значение null или имя в (: test), он выдаст все строки !!!

Вы должны создать некоторую табличную функцию "строковый токенизатор". Это может быть полезно и для других алгоритмов.

create function regexp_tokenize(
  source clob(2M)
, pattern varchar(128))
returns table (seq int, tok varchar(4000))
contains sql
deterministic
no external action
return
select seq, tok
from xmltable('for $id in tokenize($s, $p) return <i>{string($id)}</i>' 
passing 
  source as "s"
, pattern as "p"
columns 
  seq for ordinality
, tok varchar(4000) path '.'
) t;

Теперь мы можем сделать следующее:

with sample (id, name) as (values
 (1, 'ex1')
,(2, 'ex2')
,(3, 'ex3')
)
select s.*
from sample s
join table(regexp_tokenize(coalesce('ex1,ex2', s.name), ',')) f on f.tok=s.name
--join table(regexp_tokenize(coalesce(cast(null as varchar(10)), s.name), ',')) f on f.tok=s.name
--join table(regexp_tokenize(coalesce(:test, s.name), ',')) f on f.tok=s.name
;

На самом деле, из соображений производительности лучше создавать разные операторы для ввода NULL и NOT NULL.

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