Запрос в таблицу базу данных (SQL), раздробление поля с большим значением, для получения новой таблицы
Есть поле в некой таблице SQL (MSSQLServer запрос пишу на Microsoft SQL Server Management Studio)
условно выглядит так (поле типа Varchar) //2-3 записей достаточно(комментарий @Akina), ниже данные из одного поля
ПолеМногогранное
ключ1 : значение1 / ключ2 : значение2 / ключ3 : значение3
ключ1 : значение4 / ключ2 : значение5 / ключ3 : значение6
ключ1 : значение7 / ключ2 : значение8 / ключ3 : значение9
На выходе необходима новая таблица с полями-ключ

Вопрос : Какой запрос SELECT (ne Insert, ni Create, ni Delete..., потому что данные просто НАДО ИЗВЛЕЧЬ. Добавила эту строчку, потому что второй ответ уже с Insert) я могу реализовать, есть ли возможность детектировать некий ключ(?назовем условно ключ, но это повторюсь пользователь просто вводит вручную "что-то,двоеточие,слеш"), значение, и разделители в одном поле. То есть пользователь заполняет сам, не автоматизированно (опускаю вопрос, опечатки, отсутствие неких ключей, забыли поставить разделитель, пока не важно) (Пока условно нужно отталкиваться, как если бы пользователь ввел все правильно...)
Просто что то вроде :
select
t.ПолеМногогранное(и тут наверно что то мне незнакомое по умолчанию) as Ключ1,
t.ПолеМногогранное(а если нет, то КАК) as Ключ2,
t.ПолеМногогранное(выбрать часть из общей информации поля) as Ключ3
from ТаблицаНекая t
Ответы (2 шт):
Ну например
WITH cte AS (
SELECT test.id,
TRIM(SUBSTRING(splitted.value, 1, CHARINDEX(':', splitted.value) - 1)) [key],
TRIM(SUBSTRING(splitted.value, 1 + CHARINDEX(':', splitted.value), LEN(splitted.value))) value
FROM test
CROSS APPLY STRING_SPLIT(test.val, '/') AS splitted
)
SELECT id,
MAX(CASE WHEN [key] = N'ключ1' THEN value END) [ключ1],
MAX(CASE WHEN [key] = N'ключ2' THEN value END) [ключ2],
MAX(CASE WHEN [key] = N'ключ3' THEN value END) [ключ3]
FROM cte
GROUP BY id
Ваши данные очень похожи на формат Json. Вот решение на основе SQL Server 2016 и более поздних версий.
То, что я вам предоставил, называется "Минимальный воспроизводимый пример". Для справки: Как создать минимальный, самодостаточный и воспроизводимый пример https://ru.stackoverflow.com/help/minimal-reproducible-example
(1) Вы можете скопировать его в SSMS, и он должен работать на вашем компьютере в вашей среде.
Раздел «DDL and sample data population» предназначен только для имитации вашей среды, потому что у меня нет вашей база данных (СУБД).
(2) Чтобы сработалo в вашей реальной среде, вам нужно внести несколько небольших изменений в предоставленный T-SQL:
- Игнорируйте DDL, который больше не нужен, и сосредоточьтесь на
операторах CTE и
SELECT. - Замените @tbl своим настоящим именем таблицы. Замените val своим настоящим именем столбца.
SQL #1, на основе Json
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY KEY, val NVARCHAR(255));
INSERT INTO @tbl VALUES
(N'ключ1 : значение1 / ключ2 : значение2 / ключ3 : значение3'),
(N'ключ1 : значение4 / ключ2 : значение5 / ключ3 : значение6'),
(N'ключ1 : значение7 / ключ2 : значение8 / ключ3 : значение9');
-- DDL and sample data population, end
DECLARE @separator CHAR(3) = ' / '
, @separatorJson CHAR(3) = '","'
, @colon CHAR(3) = ' : '
, @colonJson CHAR(3) = '":"';
;WITH rs AS
(
SELECT ID
, N'{"' +
REPLACE(REPLACE(val,@colon, @colonJson), @separator, @separatorJson) +
N'"}' AS DataJson
FROM @tbl
)
SELECT ID
, JSON_VALUE(DataJson, N'$."ключ1"') AS [ключ1]
, JSON_VALUE(DataJson, N'$."ключ2"') AS [ключ2]
, JSON_VALUE(DataJson, N'$."ключ3"') AS [ключ3]
FROM rs;
Результат
+----+-----------+-----------+-----------+
| id | ключ1 | ключ2 | ключ3 |
+----+-----------+-----------+-----------+
| 1 | значение1 | значение2 | значение3 |
| 2 | значение4 | значение5 | значение6 |
| 3 | значение7 | значение8 | значение9 |
+----+-----------+-----------+-----------+
SQL #2, на основе XML
;WITH rs AS
(
SELECT id
, TRY_CAST('<root><r><![CDATA[' +
REPLACE(val, @separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML) AS xmldata
FROM @tbl
), cte AS
(
SELECT id
, c.value('(r[1]/text())[1]', 'NVARCHAR(50)') AS col1
, c.value('(r[2]/text())[1]', 'NVARCHAR(50)') AS col2
, c.value('(r[3]/text())[1]', 'NVARCHAR(50)') AS col3
FROM rs CROSS APPLY xmldata.nodes('/root') AS t(c)
)
SELECT id
, STUFF(col1, 1, CHARINDEX(@colon, col1,1) + 2, '') AS [ключ1]
, STUFF(col2, 1, CHARINDEX(@colon, col2,1) + 2, '') AS [ключ2]
, STUFF(col3, 1, CHARINDEX(@colon, col3,1) + 2, '') AS [ключ3]
FROM cte;