Один из подходов состоит в том, чтобы преобразовать список, разделенный запятой, в XML, извлекать значения из XML, удалять назначенного жертвы и собирать все оставшееся.
-- Sample data.
declare @ListsOfNumbers as Table (Id Int Identity, BadThing VarChar(256));
insert into @ListsOfNumbers values
('1,2,3,4'), ('11,1,1,3'), ('4,2,1'), ('1');
select * from @ListsOfNumbers;
-- Make a new mess.
declare @ValueToDrop as Int = 1;
-- Just to see what's going on: show everything.
select *
from (
select Id, BadThing,
Cast('<root><csv>' + Replace(BadThing, ',', '</csv><csv>') + '</csv></root>' as XML) as XMLBadThing
from @ListsOfNumbers) as PH cross apply
(select Val.value('.', 'integer') as Val
from XMLBadThing.nodes('root/csv') as SeparatedValues(Val)) as OtherPH;
-- Just to see what's going on: without the specified target.
select *
from (
select Id, BadThing,
Cast('<root><csv>' + Replace(BadThing, ',', '</csv><csv>') + '</csv></root>' as XML) as XMLBadThing
from @ListsOfNumbers) as PH cross apply
(select Val.value('.', 'integer') as Val
from XMLBadThing.nodes('root/csv') as SeparatedValues(Val)) as OtherPH
where Val <> @ValueToDrop;
-- Go from the sample data to regrouped stuff without the target value.
with BadThings as (
select Id, BadThing, XMLBadThing, Val
from (
select Id, BadThing,
Cast('<root><csv>' + Replace(BadThing, ',', '</csv><csv>') + '</csv></root>' as XML) as XMLBadThing
from @ListsOfNumbers) as PH cross apply
(select Val.value('.', 'integer') as Val
from XMLBadThing.nodes('root/csv') as SeparatedValues(Val)) as OtherPH
where Val <> @ValueToDrop)
select distinct Id, NewBadThing
from BadThings as BT cross apply
(select Stuff((select ',' + Cast(Val as VarChar(10))
from BadThings where Id = BT.Id order by Val for XML path(''), type).value('.[1]', 'VarChar(max)'), 1, 1, '') as NewBadThing) as X
UPDATE
Слегка опрятнее версия окончательного запроса:
with BadThings as (-- @ListsOfNumbers with the comma-delimited list converted to an XML column.
select Id, BadThing,
Cast('<root><csv>' + Replace(BadThing, ',', '</csv><csv>') + '</csv></root>' as XML) as XMLBadThing
from @ListsOfNumbers),
BadThingValues as (-- BadThings with the XML parsed to produce one value per row.
select Id, BadThing, XMLBadThing, BadThingNodes.XMLNode.value('.', 'integer') as BadThingValue
from BadThings as BT cross apply
XMLBadThing.nodes('root/csv') as BadThingNodes(XMLNode))
-- select * from BadThings; -- To see the first step in the CTE use this SELECT .
-- select * from BadThingValues; -- To see the second step in the CTE use this SELECT .
select distinct BTV.Id, BTV.BadThing, Coalesce(CDL.NewBadThing, '') as NewBadThing
from BadThingValues as BTV cross apply
(select Stuff((select ',' + Cast(BadThingValue as VarChar(10))
from BadThingValues
where Id = BTV.Id and BadThingValue <> @ValueToDrop
for XML path(''), type).value('.[1]', 'VarChar(max)'), 1, 1, '') as NewBadThing) as CDL;
Никогда, никогда не хранить данные в виде разделенных запятыми элементов. Это вызовет у вас массу проблем. – jarlh
Почему вы не используете правильную модель в первую очередь? Храните их в отдельной таблице, которая связана с основной таблицей с помощью внешнего ключа –
Как насчет поиска одной из популярных табличных функций (TVF), которые разделяют строку, разделенную запятыми, на столбец значений, Не хотите, а потом испортил остаток обратно во что-то злое? – HABO