Разделенные запятыми значения в поле базы данных - PullRequest
6 голосов
/ 10 апреля 2009

У меня есть таблица продуктов. Каждая строка в этой таблице соответствует отдельному продукту и идентифицируется уникальным идентификатором. Теперь каждый продукт может иметь несколько «кодов», связанных с этим продуктом. Например:

Id     |    Code
----------------------
0001   |   IN,ON,ME,OH
0002   |   ON,VI,AC,ZO
0003   |   QA,PS,OO,ME

То, что я пытаюсь сделать, - это создать хранимую процедуру, чтобы я мог передать коды, такие как «ON, ME», и заставить ее возвращать каждый продукт, содержащий код «ON» или «ME». Так как коды разделены запятыми, я не знаю, как их разделить и найти. Это возможно с использованием только TSQL?

Редактировать: Это критически важный стол. У меня нет полномочий его менять.

Ответы [ 11 ]

11 голосов
/ 10 апреля 2009

Вы должны хранить коды в отдельной таблице, так как у вас есть отношения многие ко многим. Если вы их разделите, то вы легко сможете проверить.

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

Если вы попытаетесь пойти по текущему пути: Вам придется разбить входную строку, потому что ничто не гарантирует, что коды в каждой записи находятся в том же порядке (или непрерывно), что и входной параметр. Тогда вам придется сделать

Code LIKE '%IN%'
AND Code Like '%QA%'

запрос с дополнительным оператором для каждого проверяемого кода. Очень неэффективно.

Идея UDF ниже также является хорошей идеей. Однако, в зависимости от размера ваших данных и частоты запросов и обновлений, у вас также могут возникнуть проблемы.

Можно ли создать дополнительную нормализованную таблицу, синхронизированную по расписанию (или на основе триггера), по которой вы будете делать запросы?

8 голосов
/ 10 апреля 2009

Во-первых, давайте сделаем исходную таблицу такой:


Id   | Value
-----+------
0001 | IN
0001 | ME
0001 | OH
0001 | ON
0002 | AC
0002 | ON
0002 | VI
0002 | ZO
0003 | ME
0003 | OO
0003 | PS
0003 | QA

Это достигается путем анализа значений, разделенных запятыми, в строки. Затем используйте мощное ключевое слово CROSS APPLY, чтобы объединиться с исходной таблицей и получить ее идентификатор. Следующий шаг - просто запросить этот CTE.


create function FnSplitToTable
(
    @param nvarchar(4000)
)
returns table as
return
    with
    Num(Pos) as -- list of positions, numbered from 1 to 4000, largest nvarchar
    (
        select cast(1 as int)
        union all 
        select cast(Pos + 1 as int) from Num where Pos < 4000
    )
    select substring(@Param, Pos, 
        charindex(',', @Param + ',', Pos) - Pos) as Value
        from Num where Pos <= convert(int, len(@Param)) 
        and substring(',' + @Param, Pos, 1) = ','
go


create proc ProcGetProductId
(
    @Codes nvarchar(4000)
)
as
with
Src
(
    Id,
    Code
)
as
(
    select '0001', 'IN,ON,ME,OH'
    union all
    select '0002', 'ON,VI,AC,ZO'
    union all
    select '0003', 'QA,PS,OO,ME'
),
Parse as
(
    select 
        s.Id, 
        f.Value
    from 
        Src as s
    cross apply
        FnSplitToTable(s.Code) as f 
)
select distinct 
    p.Id
from 
    Parse as p
join
    FnSplitToTable(@Codes) as f
on
    p.Value = f.Value
option (maxrecursion 4000)
go

exec ProcGetProductId 'IN,ME' -- returns 0001 & 0003
7 голосов
/ 10 апреля 2009

Все остальные, похоже, очень хотят сказать вам, что вы не должны этого делать, хотя я не вижу четкого объяснения, почему бы и нет.

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

Проще говоря, ядро ​​СУБД не может вести какой-либо быстрый список строк, содержащих код «AC», если вы не разбиваете его на отдельную таблицу или не помещаете в столбец самостоятельно. .

Теперь, если у вас есть другие критерии в ваших инструкциях SELECT, которые будут ограничивать число строк до некоторого управляемого числа, тогда, возможно, это будет хорошо, но в противном случае я бы, если вы можете, попытался бы избежать этого решения и сделать то, что вам уже сказали другие, разбейте на отдельные таблицы.

Теперь, если вы застряли с этим дизайном, вы можете выполнить поиск, используя запрос следующего типа:

...
WHERE ',' + Code + ',' LIKE '%,AC,%'

Это будет:

  • Соответствие 'ON, VI, AC, ZO'
  • Не соответствует 'ON, VI, TAC, ZO'

Я не знаю, является ли последний вариант приемлемым в вашем случае, если у вас есть только двухбуквенные коды, вы можете использовать только это:

...
WHERE Code LIKE '%AC%'

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

5 голосов
/ 10 апреля 2009

Хотя все предыдущие постеры верны в отношении нормализации вашей схемы БД, вы можете делать то, что вы хотите, используя «Табличный UDF», который принимает строку с разделителями и возвращает таблицу с одной строкой на значение в строке ... Вы можете использовать эту таблицу как любую другую таблицу в вашем сохраненном процессе, присоединиться к ней и т. Д. ... это решит вашу непосредственную проблему ...

Вот ссылка на такой UDF: FN_Split UDF

Хотя в статье говорится об использовании его для передачи списка значений данных с разделителями в хранимый процесс, вы можете использовать тот же UDF для работы со строкой с разделителями, хранящейся в столбце существующей таблицы ...

4 голосов
/ 22 мая 2010

Вопрос больше 1 года, но все же думал, что он будет полезен Вы можете использовать функцию FIND_IN_SET MySql. Я не уверен, поддерживают ли это другие СУБД.

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

SELECT * FROM `table_name` WHERE FIND_IN_SET('AC', `Code`) > 0
4 голосов
/ 10 апреля 2009

То, как вы храните данные, нарушает правила нормализации. Только одно атомное значение должно храниться в каждом поле. Вы должны хранить каждый предмет в одной строке.

0 голосов
/ 23 сентября 2014

, если вы хотите сделать это с php и mysql это может быть любое количество ключевых слов без ограничений

$var = explode(',',"ahmad,sayeed,asmal,babu");
$query = "SELECT * FROM post WHERE post_tags LIKE '%a%' "; 
$query1=NULL;
foreach($var as  $value)
{   
    $query1.= " OR post_tags LIKE '%$value%' ";
}

echo "$query  $query1";

ВЫВОД:

SELECT * FROM post, ГДЕ post_tags LIKE '% a%' ИЛИ ​​post_tags LIKE '% ahmad%' ИЛИ ​​post_tags LIKE '% sayeed%' ИЛИ ​​post_tags LIKE '% asmal%' ИЛИ post_tags LIKE '% babu%'

0 голосов
/ 12 октября 2012

Хотя в вашем случае будет работать простой LIKE, вот решение, как разбирать строки, разделенные запятыми Нормализация таблиц (Разобрать поля, разделенные запятыми, в отдельные записи) .

0 голосов
/ 26 июня 2012

1-й шаг: код для создания функции

<font face="Courier New" size="2">
<font color = "blue">CREATE</font>&nbsp;<font color = "blue">FUNCTION</font>&nbsp;<font color = "maroon">[dbo]</font><font color = "silver">.</font><font color = "#FF0080"><b>[Udflistofids]</b></font>&nbsp;<font color = "maroon">(</font>
<br/><font color = "green"><i>&#45;&#45;&nbsp;Add&nbsp;the&nbsp;parameters&nbsp;for&nbsp;the&nbsp;function&nbsp;here</i></font>
<br/><font color = "#8000FF">@ListOfIDs</font>&nbsp;<font color = "blue">AS</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "maroon">max</font><font color = "maroon">)</font>
<br/><font color = "green"><i>&#45;&#45;,&nbsp;@IDsSeperationChar&nbsp;as&nbsp;varchar(5)&nbsp;=&nbsp;','</i></font>
<br/><font color = "silver">,</font>
<br/><font color = "#8000FF">@UniqueID1</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/><font color = "#8000FF">@UniqueID2</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/><font color = "#8000FF">@UniqueID3</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/><font color = "#8000FF">@UniqueID4</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/><font color = "#8000FF">@UniqueID5</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "maroon">)</font>
<br/><font color = "maroon">returns</font>&nbsp;<font color = "#8000FF">@TabListOfIDs</font>&nbsp;<font color = "blue">TABLE</font>&nbsp;<font color = "maroon">(</font>
<br/>&nbsp;&nbsp;<font color = "green"><i>&#45;&#45;&nbsp;Add&nbsp;the&nbsp;column&nbsp;definitions&nbsp;for&nbsp;the&nbsp;TABLE&nbsp;variable&nbsp;here</i></font>
<br/>&nbsp;&nbsp;<font color = "maroon">id</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">50</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;<font color = "maroon">uniqueid1</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;<font color = "maroon">uniqueid2</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;<font color = "maroon">uniqueid3</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;<font color = "maroon">uniqueid4</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;<font color = "maroon">uniqueid5</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">250</font><font color = "maroon">)</font><font color = "maroon">)</font>
<br/><font color = "blue">AS</font>
<br/>&nbsp;&nbsp;<font color = "blue">BEGIN</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "green"><i>&#45;&#45;&nbsp;Fill&nbsp;the&nbsp;table&nbsp;variable&nbsp;with&nbsp;the&nbsp;rows&nbsp;for&nbsp;your&nbsp;result&nbsp;set</i></font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">DECLARE</font>&nbsp;<font color = "#8000FF">@Pos</font>&nbsp;<font color = "blue">AS</font>&nbsp;<font color = "black"><i>INT</i></font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">DECLARE</font>&nbsp;<font color = "#8000FF">@ID</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">AS</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">50</font><font color = "maroon">)</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "#8000FF">@IDsSeperationChar</font>&nbsp;<font color = "blue">AS</font>&nbsp;<font color = "black"><i>VARCHAR</i></font><font color = "maroon">(</font><font color = "black">5</font><font color = "maroon">)</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "red">','</font>
<br/>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "green"><i>&#45;&#45;SET&nbsp;@ListOfIDs&nbsp;=&nbsp;REPLACE(&nbsp;@ListOfIDs,&nbsp;&nbsp;@IDsSeperationChar,&nbsp;',')</i></font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">SET</font>&nbsp;<font color = "#8000FF">@ListOfIDs</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "fuchsia"><i>Ltrim</i></font><font color = "maroon">(</font><font color = "fuchsia"><i>Rtrim</i></font><font color = "maroon">(</font><font color = "#8000FF">@ListOfIDs</font><font color = "maroon">)</font><font color = "maroon">)</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "silver">+</font>&nbsp;<font color = "#8000FF">@IDsSeperationChar</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">SET</font>&nbsp;<font color = "#8000FF">@Pos</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "fuchsia"><i>Patindex</i></font><font color = "maroon">(</font><font color = "red">'%'</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "#8000FF">@IDsSeperationChar</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "red">'%'</font><font color = "silver">,</font>&nbsp;<font color = "#8000FF">@ListOfIDs</font><font color = "maroon">)</font>
<br/>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "green"><i>&#45;&#45;SET&nbsp;@Pos&nbsp;=&nbsp;CHARINDEX(@IDsSeperationChar,&nbsp;@ListOfIDs,&nbsp;1)</i></font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">IF</font>&nbsp;<font color = "fuchsia"><i>Replace</i></font><font color = "maroon">(</font><font color = "#8000FF">@ListOfIDs</font><font color = "silver">,</font>&nbsp;<font color = "#8000FF">@IDsSeperationChar</font><font color = "silver">,</font>&nbsp;<font color = "red">''</font><font color = "maroon">)</font>&nbsp;<font color = "silver">&lt;&gt;</font>&nbsp;<font color = "red">''</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">BEGIN</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">WHILE</font>&nbsp;<font color = "#8000FF">@Pos</font>&nbsp;<font color = "silver">&gt;</font>&nbsp;<font color = "black">0</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">BEGIN</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">SET</font>&nbsp;<font color = "#8000FF">@ID</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "fuchsia"><i>Ltrim</i></font><font color = "maroon">(</font><font color = "fuchsia"><i>Rtrim</i></font><font color = "maroon">(</font><font color = "fuchsia"><i>LEFT</i></font><font color = "maroon">(</font><font color = "#8000FF">@ListOfIDs</font><font color = "silver">,</font>&nbsp;<font color = "#8000FF">@Pos</font>&nbsp;<font color = "silver">-</font>&nbsp;<font color = "black">1</font><font color = "maroon">)</font><font color = "maroon">)</font><font color = "maroon">)</font>
<br/>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">IF</font>&nbsp;<font color = "#8000FF">@ID</font>&nbsp;<font color = "silver">&lt;&gt;</font>&nbsp;<font color = "red">''</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">BEGIN</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">INSERT</font>&nbsp;<font color = "blue">INTO</font>&nbsp;<font color = "#8000FF">@TabListOfIDs</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">(</font><font color = "maroon">id</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">uniqueid1</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">uniqueid2</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">uniqueid3</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">uniqueid4</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">uniqueid5</font><font color = "maroon">)</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">VALUES</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">(</font><font color = "#8000FF">@ID</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "#8000FF">@UniqueID1</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "#8000FF">@UniqueID2</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "#8000FF">@UniqueID3</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "#8000FF">@UniqueID4</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "#8000FF">@UniqueID5</font><font color = "maroon">)</font>&nbsp;<font color = "green"><i>&#45;&#45;Use&nbsp;Appropriate&nbsp;conversion</i></font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">END</font>
<br/>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">SET</font>&nbsp;<font color = "#8000FF">@ListOfIDs</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "fuchsia"><i>RIGHT</i></font><font color = "maroon">(</font><font color = "#8000FF">@ListOfIDs</font><font color = "silver">,</font>&nbsp;<font color = "fuchsia"><i>Len</i></font><font color = "maroon">(</font><font color = "#8000FF">@ListOfIDs</font><font color = "maroon">)</font>&nbsp;<font color = "silver">-</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "fuchsia"><i>Len</i></font><font color = "maroon">(</font><font color = "#8000FF">@ID</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "#8000FF">@IDsSeperationChar</font><font color = "maroon">)</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">)</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">SET</font>&nbsp;<font color = "#8000FF">@Pos</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "fuchsia"><i>Patindex</i></font><font color = "maroon">(</font><font color = "red">'%'</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "#8000FF">@IDsSeperationChar</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "red">'%'</font><font color = "silver">,</font>&nbsp;<font color = "#8000FF">@ListOfIDs</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">)</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "green"><i>&#45;&#45;SET&nbsp;@Pos&nbsp;=&nbsp;CHARINDEX(@IDsSeperationChar,&nbsp;@ListOfIDs,&nbsp;1)</i></font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">END</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">END</font>
<br/>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "blue">RETURN</font>
<br/>&nbsp;&nbsp;<font color = "blue">END</font>
<br/>
<br/><font color = "maroon">go</font>&nbsp;
</font>


**2nd Step : Code to get the result**

<font face="Courier New" size="2">
<font color = "blue">DECLARE</font>&nbsp;<font color = "#8000FF">@udvMax</font>&nbsp;<font color = "black"><i>NVARCHAR</i></font><font color = "maroon">(</font><font color = "maroon">max</font><font color = "maroon">)</font>
<br/>
<br/><font color = "blue">SELECT</font>&nbsp;<font color = "#8000FF">@udvMax</font>&nbsp;<font color = "silver">=</font>&nbsp;<font color = "red">''</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "fuchsia"><i>Substring</i></font><font color = "maroon">(</font>&nbsp;<font color = "maroon">(</font>&nbsp;<font color = "blue">SELECT</font>&nbsp;<font color = "red">'&nbsp;Union&nbsp;'</font>&nbsp;<font color = "silver">+</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "red">'Select&nbsp;*&nbsp;from&nbsp;dbo.udfListOfIDs('''</font>&nbsp;<font color = "silver">+</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "maroon">tmpu</font><font color = "silver">.</font><font color = "maroon">code</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "red">''',&nbsp;'''</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "maroon">tmpu</font><font color = "silver">.</font><font color = "maroon">id</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "red">''',&nbsp;'''</font>&nbsp;<font color = "silver">+</font>&nbsp;<font color = "maroon">tmpu</font><font color = "silver">.</font><font color = "maroon">code</font>&nbsp;<font color = "silver">+</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "red">''',&nbsp;null,null,null&nbsp;)'</font>&nbsp;<font color = "blue">FROM</font>&nbsp;<font color = "maroon">tmpu</font>&nbsp;<font color = "blue">FOR</font>&nbsp;<font color = "maroon">xml</font>&nbsp;<font color = "maroon">path</font><font color = "maroon">(</font><font color = "red">''</font><font color = "maroon">)</font><font color = "maroon">)</font><font color = "silver">,</font>&nbsp;<font color = "black">7</font><font color = "silver">,</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "black">200000</font><font color = "maroon">)</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "silver">+</font>
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color = "red">'&nbsp;Order&nbsp;by&nbsp;UniqueID1,&nbsp;UniqueID2,&nbsp;UniqueID3,&nbsp;UniqueID4,&nbsp;UniqueID5,&nbsp;ID'</font>
<br/>
<br/><font color = "green"><i>&#45;&#45;Select&nbsp;@udvMax</i></font>
<br/><font color = "blue">EXECUTE</font>&nbsp;<font color = "#FF0080"><b>Sp_executesql</b></font>
<br/>&nbsp;&nbsp;<font color = "#8000FF">@udvMax</font>&nbsp;
</font>

**** Возможно, вам понадобится добавить критерии в операторе выбора на втором шаге. **

Надеюсь, это поможет вам.

JP * * +1010

0 голосов
/ 21 апреля 2009

Я согласен с другими постерами, что вам следует внимательно изучить нормализацию схемы, но я также знаю, что ярлыки являются частью жизни.

Вот пример функции, написанной на диалекте Sybase, которая делает то, что вы делаете:

ALTER FUNCTION "DBA"."f_IsInStringList"( IN @thisItem char(2), IN @thisList varchar(4000) )
RETURNS INTEGER
DETERMINISTIC
BEGIN


DECLARE is_member bit;
DECLARE LOCAL TEMPORARY TABLE tmp (thisItem  char(2)) ;
DECLARE @tempstring varchar(10);
DECLARE @count integer;

IF LENGTH(TRIM(@thisList)) > 0 THEN

    WHILE LENGTH(TRIM(@thisList)) > 0  LOOP
       -- loop over comma-separated list and stuff members into temp table
       IF LOCATE ( @thisList, ',' , 1) > 0 THEN

           SET @count = LOCATE ( @thisList, ',' , 1);
           SET @tempstring = SUBSTRING ( @thisList, 1,@count-1 );

           INSERT INTO tmp ( thisItem  ) VALUES (  @tempstring );
           SET @thisList = STUFF ( @thisList, 1, @count, '' )

        ELSE

            INSERT INTO tmp ( thisItem  ) VALUES ( @thisList );
            SET @thisList = NULL;

        END IF;

    END LOOP ;

END IF;

IF EXISTS (SELECT * FROM tmp WHERE thisItem   = @thisItem ) THEN
    SET is_member = 1;
ELSE
    SET is_member = 0 ;
END IF ;

    RETURN is_member;
END

Затем вы можете создать простой запрос, чтобы проверить, встречается ли значение в строке через запятую:

select * from some_table t 
         WHERE f_IsInStringList('OR', t.your_comma_separated_column) = 1 OR
               f_IsInStringList('ME', t.your_comma_separated_column) = 1 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...