Sql Server, разделяющий значение столбца на адрес электронной почты и имя

#sql #sql-server

#sql #sql-сервер

Вопрос:

Я новичок в sql. Мне нужна помощь с отделением 2 значений от значения столбца.

Пример значения столбца:

 Sam Taylor <Sam.Taylor@gmail.com>
  

Мне нужны 2 столбца из этого столбца.

 Name         Email
Sam Taylor   Sam.Taylor@gmail.com
  

TIA

https://www.db-fiddle.com/f/beu4tdDo4WFAwKXtt9KL8A/0

Комментарии:

1. Пожалуйста, укажите в своем вопросе базу данных, которую вы используете: mysql, postgresql, oracle …? Строковые функции сильно зависят от поставщика.

2. какую СУБД вы используете?

3. SQL Server Management studio

4. Это может помочь sqlservertutorial.net/sql-server-string-functions /…

5. SSMS — это клиентский инструмент, а не база данных. В любом случае вы не должны хранить такие данные в базе данных, это нарушает самое основное правило проектирования, 1-ю обычную форму. Одно поле должно содержать только одну вещь

Ответ №1:

 DECLARE @yourField nvarchar(100)='Sam Taylor <Sam.Taylor@gmail.com>'


SELECT  SUBSTRING (@yourField ,0,CHARINDEX('<',@yourField)) as Name,  SUBSTRING (@yourField ,CHARINDEX('<',@yourField) 1,CHARINDEX('>',@yourField)-CHARINDEX('<',@yourField)-1)  as Email
  

Ответ №2:

Один из способов сделать это будет таким, как показано ниже, но при условии, что у вас нет данных < или > в качестве имени.

 select datastring, 
        name=max(case when row=1 then value else null end),
        email=max(case when row=2 then value else null end)
    from
    (
    select
        datastring,
        value=REPLACE(value,'>',''),
        row=row_number() over (partition by datastring order by datastring)
    from yourtable 
    cross apply STRING_SPLIT(datastring,'<')
    )t
    group by datastring 
  

Комментарии:

1. STRING_SPLIT() не гарантирует упорядочение результатов. Таким образом, этот метод не гарантированно работает.

Ответ №3:

Вы можете использовать string_split() , но вот так:

 select t.*, v.*
from t cross apply
     (select max(case when s.value not like '%@%>' then trim(s.value) end) as name,
             max(case when s.value like '%@%>' then replace(s.value, '>', '') end) as email             
      from string_split(t.full_email, '<') s
     ) v;
  

В более старых версиях вы можете использовать:

 select ltrim(rtrim(left(full_email, charindex('<', full_email) - 1))) as name,
       replace(stuff(full_email, 1, charindex('<', full_email), ''), '>', '') as name
from t;
  

Здесь есть db<>fiddle.