Существует ли строковое значение в списке строк |Redshift Query - PullRequest
0 голосов
/ 04 мая 2019

У меня есть некоторые интересные данные, я пытаюсь выполнить запрос, однако не могу получить правильный синтаксис.У меня есть временная таблица (temp_id), которую я заполнил значениями id, которые мне нужны.В этом примере это только два идентификатора.

CREATE TEMPORARY TABLE temp_id (id bigint PRIMARY KEY);
INSERT INTO temp_id (id) VALUES ( 1 ), ( 2 );

У меня есть другая таблица в производстве (назовем ее foo), которая содержит кратные эти идентификаторы в одной ячейке.Столбец ids выглядит следующим образом (ниже) с идентификаторами в виде одной строки, разделенной "|"

ids 
-----------
1|9|3|4|5
6|5|6|9|7
NULL
2|5|6|9|7
9|11|12|99

Я хочу оценить каждую ячейку в foo.ids и посмотреть, есть ли какая-либо из ids в соответствии с теми, что в моей таблице temp_id.

Ожидаемый результат

ids         |does_match
-----------------------
1|9|3|4|5   |true
6|5|6|9|7   |false
NULL        |false
2|5|6|9|7   |true
9|11|12|99  |false

Пока я придумал это, но, похоже, ничего не могу вернуть.Вместо того, чтобы пытаться создать новый столбец does_match, я попытался выполнить фильтрацию внутри оператора WHERE.Однако проблема в том, что я не могу понять, как вычислить все значения id в моей временной таблице для строкового блоба, заполненного ids в foo.

SELECT
    ids,
FROM foo
WHERE ids = ANY(SELECT LISTAGG(id, ' | ') FROM temp_ids)

Любые предложения будутполезно.

ура,

Ответы [ 2 ]

1 голос
/ 04 мая 2019

это будет работать, но не уверен насчет производительности

SELECT
    ids
FROM foo
JOIN temp_ids 
ON '|'||foo.ids||'|' LIKE '%|'||temp_ids.id::varchar||'|%'

вы заключаете список идентификаторов в пару дополнительных разделителей, так что вы всегда можете найти |id|, включая первое и последнее число

1 голос
/ 04 мая 2019

Следующий SQL (я знаю, что это немного хакерство) возвращает именно то, что вы ожидаете в качестве вывода, протестированный с вашими примерами данных, не знаю, как он будет вести себя на ваших реальных данных, попробуйте и дайте мне знать

with seq AS (                # create a sequence CTE to implement postgres' unnest
select 1 as i union all      # assuming you have max 10 ids in ids field, 
                             # feel free to modify this part
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6 union all
select 7 union all
select 8 union all
select 9 union all
select 10)

select distinct ids, 
    case             # since I can't do a max on a boolean field, used two cases 
                     # for 1s and 0s and converted them to boolean
       when max(case        
          when t.id in (
                select split_part(ids,'|',seq.i) as tt
                  from seq
                  join foo f on seq.i <= REGEXP_COUNT(ids, '|') + 1
                 where tt != '' and k.ids = f.ids)
          then 1 
          else 0 
          end) = 1 
       then true 
       else false 
    end as does_match
from temp_id t, foo 
group by 1

Пожалуйста, дайте мне знать, если это работает для вас!

...