#sql #postgresql
Вопрос:
У меня есть таблица, в которой в одном из столбцов таблицы third_row
хранится разделенный запятыми список чисел в виде строки, но когда его значение равно A
, это означает комбинацию всех возможных чисел. Как мне подойти к этому так, чтобы запрос возвращал все строки, в которых есть third_row
as A
, а остальные where third_row
равны одному из значений в строке, разделенной запятыми?
Для справки, вот формат таблицы:
first_row | second_row | third_row |
---|---|---|
0028001070200 | 50 | A |
0049048000701 | 51 | 01,04,02,31, |
Я также пробовал этот запрос, но безуспешно:
SELECT
sds.scheme_code,
rs.scheme_name
FROM
trea.salary_deduction_schemes sds
LEFT JOIN
trea.receipt_schemes rs
ON sds.scheme_code = rs.scheme_code
WHERE sds.list_object_head = 'A'
OR 16 IN(regexp_split_to_table(sds.list_object_head, E','))
Комментарии:
1. Не храните данные в виде элементов, разделенных запятыми, это только вызовет у вас массу проблем.
2. Я бы предпочел использовать другую таблицу для отображения этих целых чисел, но это старый проект, который начался задолго до того, как я присоединился.
3. Это жизнь программиста, борющегося с плохими проектами других людей.
4.
WHERE sds.list_object_head = 'A' or 16 = any(string_to_array(sds.list_object_head, ',')::integer[])
Ответ №1:
Ваш метод почти работает:
WHERE sds.list_object_head = 'A' OR
16 IN (SELECT val::int
FROM regexp_split_to_table(sds.list_object_head, E',') val
)
Вы также можете использовать сопоставление строк:
WHERE ',' || sds.list_object_head || ',' LIKE '%,' || 16 || ',%'
Или вы можете преобразовать в массив и использовать операции с массивом.
Я настоятельно рекомендую найти представление, отличное от строк, для хранения целочисленных значений-предпочтительно другую таблицу или, возможно, массив.
Ответ №2:
Вы можете преобразовать список в массив и использовать = any
оператор:
WHERE sds.list_object_head = 'A'
OR 16 = any(string_to_array(trim(',' from sds.list_object_head), ',')::int[])
Это trim()
необходимо для того, чтобы избавиться от трейлинга ,
, который после применения приведет к пустой строке string_to_array()
, а это, в свою очередь, приведет к ошибке приведения, поскольку пустая строка не является допустимым целым числом.
Это, вероятно, немного быстрее, чем использовать регулярное выражение и неинвестировать массив.