Разделить с помощью нескольких разделителей sql

У меня есть вариант использования, когда мне нужно разделить строки несколькими разделителями.

ID клиента бла_бла бла-бла
select client_id ,split(client_id,'-')[0] col1` ,split(client_id,'-')[1] col2 from mytbl

возвращает

ID клиента столбец 1 столбец 2 бла-бла блин блин

Я пробовал различные перестановки, чтобы вставить два разделителя, но безуспешно.

select client_id ,split(client_id,'-'||'_')[0] col1` ,split(client_id,'-'||'_')[1] col2 from mytbl

это ошибка, но я хочу вернуть...

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

Ответы 3

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

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

select 
    client_id,
    (regexp_split_to_array(client_id, '[-_]'))[1] col1, 
    (regexp_split_to_array(client_id, '[-_]'))[2] col2 
    from mytbl;

Вот POC скрипки: https://www.db-fiddle.com/f/4jyoMCicNSZpjMt4jFYoz5/13029

Это синтаксически неправильно в двух отношениях: обычные массивы PostgreSQL основаны на 1, поэтому [0] просто даст вам null, и вам нужно заключить вызов в круглые скобки, чтобы иметь возможность подписать результирующий массив квадратными скобками, чтобы избежать еще одной синтаксической ошибки. . Скрипка, на которую вы ссылаетесь, не демонстрирует предлагаемый вами код - я не уверен, почему вы просто не протестировали там свое решение.

Zegarek 08.04.2024 20:38

Спасибо за отзыв @Zegarek — обновил фрагмент и поэкспериментировал с полным решением, а не только с POC использования regexp_split_to_array

byteSlayer 08.04.2024 20:41

Спасибо за внимание к замечанию. Хорошо, что вы протестировали и исправили корректность предложенного вами кода, но вы не заботитесь о производительности: вы утяжеляете ситуацию из-за накладных расходов на регулярные выражения и массивы. Тем не менее, после устранения проблем, если производительность достаточна для OP, решение не хуже любого другого - в конце концов, им не нужна спортивная машина, чтобы добраться из А в Б.

Zegarek 08.04.2024 20:54

Вы можете сделать это именно так, как планировали, при условии, что вы translate() все альтернативные разделители по сравнению с тем, который вы хотите использовать: демо

select client_id
  , split_part(client_id2,'-',1)
  , split_part(client_id2,'-',2)
from mytbl cross join lateral
(values(translate(client_id,'_;/','---'))) as v(client_id2)
ID клиента разделенная_часть разделенная_часть бла_бла бла бла бла-бла блин блин

В этом подходе приятно то, что он работает быстрее по сравнению с идеями регулярного выражения + массива. Демо показывает, что этот метод работает на 3x быстрее на случайных выборках размером 10–300 тысяч благодаря свободе от снижения производительности, связанного с накладными расходами на регулярные выражения и массивы.

Простое решение в Databricks (поскольку в вашем вопросе есть тег Databricks)

select
  client_id,
  split(client_id, '-|_')[0] col1,
  split(client_id, '-|_')[1] col2
from
  mytbl

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

Похожие вопросы

Копирование данных из S3 в RDS Postgresql с использованием Python: «FeatureNotSupported: КОПИРОВАНИЕ из файла не поддерживается»
Не удалось установить postgresql-client-16 в контейнер докеров
ВЫБРАТЬ из двух таблиц, СОЕДИНИТЬСЯ без связи, повторяя значение в одном или другом столбце
Вопрос о плане запроса с использованием индекса btree_gist в PostgreSQL с использованием целочисленных атрибутов и атрибутов tstzrange
Как запросить таблицу, имя которой построено на основе результата функции PL/pgSQL?
Как я могу выполнить несколько операторов обновления для списка идентификаторов в PostgresSQL одновременно?
Есть ли способ сделать резервную копию существующих таблиц без подключения к серверу Postgres?
@DataJpaTest и @SpringBootTest запрашивают базу данных src/main/resources вместо базы данных src/test/resources
Как установить пароль для Posgres 16.X с помощью Docker 25.0.X?
Почему в этой функции Postgres необходимо явное имя таблицы?