Создание нескольких столбцов из одного столбца с использованием разных разделителей

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть столбец в таблице SQL. Столбец «Dam»

 SELECT Dam
FROM [dbo].[names]
  

Для большинства данных в столбце они представлены в следующем формате

Марафон Нелла (Jpn)1942

Я хотел бы обновить базу данных, чтобы разделить столбец на три с

 Dam_Name = Marathon Nella
Dam_Country = Jpn
Dam_YOB = 1942
  

Иногда / редко у меня есть только значение Dam_Name в поле, и его нет ( чтобы выступать в качестве разделителя. В этом случае я хотел бы, чтобы Dam_Name оставалось как есть, а Dam_Country и Dam_YOB были равны НУЛЮ

Я просмотрел PARSENAME, но я не был уверен, как структурировать его, если существует более эффективный способ обновления базы данных.

Любая помощь приветствуется

Ответ №1:

Можно сделать это с помощью XML-трюков:

 ;WITH splitValues AS
(
SELECT id,
           LTRIM(RTRIM(m.n.value('.[1]', 'varchar(8000)'))) AS splitValue, 
           CASE ROW_NUMBER()OVER (PARTITION BY id ORDER BY id) WHEN 1 THEN 'Name' WHEN 2 THEN 'Country' ELSE 'YOB' end AS columnHeader
    FROM
    (
        SELECT id,
               CAST('<XMLRoot><RowData><ColumnData>'
                      REPLACE(REPLACE(string, '(', '</ColumnData><ColumnData>'), ')', '</ColumnData><ColumnData>')
                      '</ColumnData></RowData></XMLRoot>' AS XML) AS xmlString
        FROM #x
    ) xmlTable
        CROSS APPLY xmlString.nodes('/XMLRoot/RowData/ColumnData') m(n))

This gives you results like:
========================
id    splitValue       columnHeader
1     Marathon Nella   Name
1     Jpn              Country
1     1942             Year
  

Следующее обновление таблицы:

    UPDATE table
   SET Name = splitValue
   From table INNER JOIN
        splitValues ON table.Id = splitValues.Id AND columnHeader = 'Name'
  

и т. д

Ответ №2:

Ну, извлечение строк в SQL Server не так просто. Предполагая, что страна состоит из трех символов:

 select left(dam, charindex('(', dam   ' (') - 2) as name,
       nullif(left(stuff(dam, 1, charindex('(', dam   '('), ''), 3), '') as country,
       nullif(stuff(dam, 1, charindex(')', dam   ')'), ''), '') as dob
from (values ('Marathon Nella (Jpn)1942'), ('testing a')) v(dam)
  

Это можно настроить, если эти условия не выполняются, но это дает представление о том, что делать.

Вот скрипка db<> .

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

1. Кажется, это помогает! Я хотел бы обновить базу данных, а не просто выбрать ее, так что это просто замена выбора на ОБНОВЛЕНИЕ dbo.names, а затем УСТАНОВИТЬ или мне нужно сначала создать столбцы?

2. @ByronRogers . , , Вы должны иметь возможность использовать эти выражения в update .