2015-07-09 3 views
1

У меня есть списки, как это хранится в поле в SQL:Поиск значения в список разделенных запятыми

Id MyListField 
1 soy, meat, milk, wheat, nuts 
2 soy, meat, nuts, milk, wheat 
3 nuts 
4 walnuts, nutshell, nuts 
5 nuts, beans 
6 walnuts, hazel nuts 
7 nutshell, nutsize 

Это не нормализуется, и я не могу изменить его. Теперь я должен найти nuts и заменить их на insane (но сохраните, например, hazel nuts и nutshell).

Поле поиска сравнительно легко, есть четыре случая, и я имею замещающий характер % в моем распоряжении:

SELECT * FROM MyTable WHERE 
    MyListField LIKE 'nuts' OR 
    MyListField LIKE 'nuts, %' OR 
    MyListField LIKE '%, nuts' OR 
    MyListField LIKE '%, nuts, %' 

Но заменить трудно, потому что у меня нет заполнителя или startofstring/endofstring символов :

UPDATE MyTable SET MyListField = 
    REPLACE(
     REPLACE(
      REPLACE(
       REPLACE(
        MyListField, 
        ', nuts, ' , 
        ', insane, ' 
       ), 
       ????, 
       ???? 
      ), 
      ????, 
      ???? 
     ), 
     ????, 
     ???? 
    ) 
WHERE 
    MyListField LIKE 'nuts' OR 
    MyListField LIKE 'nuts, %' OR 
    MyListField LIKE '%, nuts' OR 
    MyListField LIKE '%, nuts, %' 

Я могу легко заменить его в середине строки, но не в начале или в конце. Или я могу?

Я использую SQL Server 2008, если это имеет значение.

+0

Разделите данные на строки, используя функцию разделения строк, затем замените строки, в которых находится элемент, и проанализируйте все вместе, используя xml path trick –

+1

Это очень похожий вопрос: http://stackoverflow.com/questions/29574811/replace-semicolons-separated-values-with-another-table-values –

ответ

2

Если вы объединяете поле между , и _,, тогда у вас есть только один случай для поиска.

например.

update MyTable set MyFieldList = replace(', ' + MyFieldList + ',', ', nuts,', ', insane,') 
update MyTable set MyFieldList = substring(MyFieldList, 3, len(MyFieldList) - 3) 
0

Вы могли бы использовать что-то вроде

case 
    when Field = @val then @replaceVal 
    when Field like @val + ', %' then 
    @replaceVal + substring(Field, len(@val) + 1, len(Field)) 
    when Field like '%, ' + @val then 
    left(Field, len(Field) - len(@val)) + @replaceVal 

Просто добавьте все остальные варианты, и вы должны быть хорошо.

2

Поставив запятую в начале и в конце списка, каждый элемент, завернутые в ведущих «„и замыкающий“,».

Тогда ваш заменить метод становится легко ....

REPLACE(', ' + MyListField + ',', 
     ', ' + @termToReplace + ',', 
     ', ' + @replacement + ',') 

Наконец, полоса ведущие и ведомые запятые.

0

Со всей этой помощью это было легче, чем я думал.

UPDATE MyTable 
SET MyListField = 
    SUBSTRING(
     REPLACE(
      CONCAT(', ', MyListField, ', '), 
      ', nuts, ', 
      ', insane, ' 
     ), 
     3, 
     DATALENGTH(MyListField)+LEN('insane')-LEN('nuts') 
    ) 
WHERE CONCAT(', ',MyListField,', ') LIKE '%, nuts, %' 

Это работает до тех пор, пока в строке нет одного или нулевого числа. Если их может быть несколько, это провалится, но для меня это не имеет значения. Если это имеет значение для вас, не стесняйтесь размножать часть (LEN-LEN) с помощью How do you count the number of occurrences of a certain substring in a SQL varchar?

Смежные вопросы