Извлечение поля, связанного с острием трубы, в строки

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

Примеры данных

select distinct [PROV_KEY], 
[NTWK_CDS]
FROM [SPOCK].[US\AC39169].[WellPointExtract_ERR]
where [PROV_KEY] = '447358**************************'
--results
PROV_KEY NTWK_CDS
447358************************** |GA_HMO|GA_OPN|GA_PPO|GA_BD|GA_MCPPO|GA_HDPPO|

И я бы хотел:

PROV_KEY NTWK_CDS
447358************************** GA_HMO
447358************************** GA_OPN
447358************************** GA_PPO

Я попробовал следующее, но получаю только первый набор значений:

select distinct [PROV_KEY], 
substring([NTWK_CDS], 1, 
CHARINDEX('|',[NTWK_CDS], CHARINDEX('|',[NTWK_CDS])+1)) 
FROM [SPOCK].[US\AC39169].[WellPointExtract_ERR]
where [PROV_KEY] = '447358**************************'
3 ответа

Это стандартная проблема разделения строк, и есть много решений. Однако большинство из них по-прежнему считают обходным путем, поскольку SQL Server не имеет встроенной функции split.

Вы можете начать свое исследование здесь: http://www.sommarskog.se/arrays-in-sql.html


Важнейшей операцией, которую необходимо выполнить, является разделение. Существует множество решений этой проблемы (см. здесь для некоторых), и люди предпочитают разные, в зависимости от ситуации и личных предпочтений. Однако, если вы сделали раскол, вы можете ПРИСОЕДИНЯЙТЕСЬ/ПРИМЕНЯЙТЕСЬ к результатам, чтобы получить желаемый результат.

Я лично предпочитаю использовать функцию SQLCLR для этой цели, поскольку производительность, как правило, намного лучше; но количество опций там ошеломляет.


Вы можете использовать функцию расщепления

CREATE FUNCTION dbo.SplitStrings_CTE(@List nvarchar (1000), @Delimiter nvarchar(1 ))
RETURNS @returns TABLE(val nvarchar(100), [level] int, PRIMARY KEY CLUSTERED([level]))
AS
BEGIN
;WITH cte AS
 (
 SELECT SUBSTRING(@List, 0, CHARINDEX(@Delimiter , @List)) AS val ,
 CAST(STUFF(@List + @Delimiter, 1, CHARINDEX(@Delimiter, @List),'') AS nvarchar (1000)) AS stval,
 1 AS [level]
 UNION ALL
 SELECT SUBSTRING(stval, 0, CHARINDEX(@Delimiter, stval)),
 CAST(STUFF(stval, 1 , CHARINDEX(@Delimiter ,stval), '') AS nvarchar(1000)),
 [level] + 1
 FROM cte
 WHERE stval != ''
 )
 INSERT @returns
 SELECT REPLACE(val ,' ' ,'') AS val, [level]
 FROM cte
 RETURN
END

Следовательно, ваш оператор SELECT будет

SELECT *
FROM dbo.test82 t CROSS APPLY dbo.SplitStrings_CTE(t.NTWK_CDS, '|') o
WHERE o.val != ''

Демо на SQLFiddle

licensed under cc by-sa 3.0 with attribution.