У меня есть эта строка, например Green/1051;Brown/1258;Red/1110;Yellow /1024;Red/1147;

И я хотел бы иметь возможность получить следующую строку из этого 1051;1258;1110;1024;1147;

Я пробовал несколько решений, но они имеют тенденцию обслуживать одну «часть» строки. Если это невозможно, я могу отформатировать это на стороне c #, однако было бы неплохо сделать это в моей хранимой процедуре.

Благодарность

РЕДАКТИРОВАТЬ: К сожалению, это сторонний набор данных, поэтому я отформатировал эти данные с использованием C #. Исходя из ответов ниже, я согласен с тем, что SQL не предназначен для возможности извлекать и анализировать то, что мне нужно, его было бы проще поддерживать.

0
Jack Waters 11 Апр 2019 в 15:47

2 ответа

Лучший ответ

Я предполагаю, что причина, по которой данные должны быть проанализированы на сервере, состоит в том, чтобы использовать их в большем запросе. В противном случае нет причин анализировать его на сервере. Было бы намного проще сделать это в C #, например, с помощью регулярного выражения.

Не зная, какой это SQL Server, я просто предположу, что это 2016 или более поздняя версия, потому что это позволяет нам преобразовать строку в значение JSON, заменив \ на ":" и ; с ",". Подобная техника может использоваться в более старых версиях для преобразования строки в XML.

Предполагая эту простую таблицу:

declare @table table (id int identity primary key,col varchar(max))

insert into @table (col)
values ('Green/1051;Brown/1258;Red/1110;Yellow /1024;Red/1147;')

Мы можем использовать STUFF(col,len(col),1,'') для удаления завершающей точки с запятой. Этот запрос:

select stuff(col,len(col),1,'')
from @table

Дает

Green/1051;Brown/1258;Red/1110;Yellow /1024;Red/1147

Замена / и ; на

select replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","')
from @table

Дает:

Green":"1051","Brown":"1258","Red":"1110","Yellow ":"1024","Red":"1147

Нам просто нужно завершить строку JSON, окружив это значение {" и "}.

Как только мы сделаем это, мы можем использовать OPENJSON:

select *
from @table 
    cross apply openjson('{"' + replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","') + '"}')

Это вернет столбцы id, col из исходной таблицы и столбцы key, value и type из OPENJSON:

select id,[key],value
from @table 
    cross apply openjson('{"' + 
replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","') + '"}') x

Вернется :

id  key     value
1   Green   1051
1   Brown   1258
1   Red     1110
1   Yellow  1024
1   Red     1147

Мы можем объединить эти результаты с другой таблицей. Скажем, эти числа являются идентификаторами предметов, и у нас есть таблица инвентаря с суммами в магазине для каждого:

declare @inventory table (colorid int,amount int)

insert into @inventory (colorid,amount)
values
(1051,5),
(1258,10),
(1110,24),
(1024,2),
(1147,22)

Какие предметы имеют сумму выше 20?

select id, [key],colorid,amount
from @table 
    cross apply openjson('{"' + replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","') + '"}') x
inner join @inventory i on i.colorid=x.value
where amount>20

Результат:

id  key colorid amount
1   Red 1110    24
1   Red 1147    22
1
Panagiotis Kanavos 11 Апр 2019 в 13:24

Поиск DelimitedSplit8K. Это позволит вам преобразовать строку в число строк, разделяющихся на;

Затем вы можете использовать STUFF..FOR XML для перестройки строки

В качестве альтернативы, если вы знаете, что вы всегда будете хотеть ВСЕ из чисел и точек с запятой и НЕТ альфы и пробелов, которые вы могли бы использовать

REPLACE(REPLACE(instring,[A-Z],''),' ','')
0
Aaron Reese 11 Апр 2019 в 12:52