Задать вопрос
@klim76
android/java/sql

Select из строки?

Добрый день. В таблице существует столбец текстового типа, в нем содержатся наборы данных с разделителем ";".
пример:
столбцы_с_какими_то_данными строка1;строка2;строка3;
Подскажите как с помощью SQL сделать из строчки выше 3 строчки:
столбцы_с_какими_то_данными строка1;
столбцы_с_какими_то_данными строка2;
столбцы_с_какими_то_данными строка3;
Спасибо!

забыл указать. Всё это крутится на MS sql
  • Вопрос задан
  • 401 просмотр
Подписаться 2 Средний Комментировать
Решения вопроса 2
alex1t
@alex1t
.net developer
Мы на 2012 используем:
CREATE FUNCTION [dbo].[CalcHelperString_Split]
(   
    @str VARCHAR(MAX),
    @delimiter VARCHAR(10)
)
RETURNS TABLE 
AS
RETURN 
	SELECT t.c.value('(./text())[1]', 'VARCHAR(MAX)') as item
	FROM 
	( 
		SELECT x = CONVERT(XML, '<i>' + REPLACE(@str, @delimiter, '</i><i>') + '</i>').query('.')
	) a
	CROSS APPLY x.nodes('i') t(c)
	WHERE t.c.value('(./text())[1]', 'VARCHAR(MAX)') is not null;
GO

Было найдено на просторах StackOverflow. Работает быстрее всего, что мы смогли найти.

Поэтому касательно вашего запроса можно сделать так:
DECLARE @TTT TABLE (column1 VARCHAR(50), column2 VARCHAR(100))
 
INSERT INTO @TTT (column1, column2)
    VALUES('Какие-то данные 1', 'строка1;строка2;строка3;'),
        ('Какие-то данные 2', 'строка4;строка5;строка6;'),
        ('Какие-то данные 3', 'строка7;'),
        ('Какие-то данные 4', 'строка8;строка9;')

SELECT * FROM @TTT t
CROSS APPLY dbo.CalcHelperString_Split(t.column2, ';') f
Ответ написан
Комментировать
@klim76 Автор вопроса
android/java/sql
На другом ресурсе подсказали. Искал вот такую реализацию:
DECLARE @TTT TABLE (column1 VARCHAR(50), column2 VARCHAR(100))
 
INSERT INTO @TTT (column1, column2)
    VALUES('Какие-то данные 1', 'строка1;строка2;строка3;'),
        ('Какие-то данные 2', 'строка4;строка5;строка6;'),
        ('Какие-то данные 3', 'строка7;'),
        ('Какие-то данные 4', 'строка8;строка9;')
 
 
;WITH cteData (column1, column2, etalon, level)
AS
(
SELECT column1,
    SUBSTRING(REPLACE(column2,' ',''),1,CASE WHEN PATINDEX ( '%;%' , column2 )<>0 THEN PATINDEX ( '%;%' , column2 ) ELSE LEN(column2) END) AS column2, 
    SUBSTRING(REPLACE(column2,' ',''),PATINDEX ( '%;%' , column2 )+1, LEN(column2)) AS etalon,
    0 AS level 
FROM @TTT
UNION ALL
SELECT A.column1, 
        SUBSTRING(CTE.etalon,1,CASE WHEN PATINDEX ( '%;%' , CTE.etalon )<>0 THEN PATINDEX ( '%;%' , CTE.etalon ) ELSE LEN(CTE.etalon) END) AS column2,  
        CASE WHEN PATINDEX ( '%;%' , CTE.etalon )>0 THEN SUBSTRING(CTE.etalon,PATINDEX ( '%;%' , CTE.etalon )+1, LEN(CTE.etalon)) ELSE '' END AS etalon,
        CTE.level+1 AS level 
FROM @TTT A
INNER JOIN cteData CTE ON A.column1 = CTE.column1 AND len(CTE.etalon)>0
)
SELECT column1, column2
FROM cteData
ORDER BY column1, level
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
denman1985
@denman1985
SQL, Oracle Forms/Reports dbd
AndyKorg
@AndyKorg
Кнопконажиматель и припоерасплавлятель
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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