Хранение идентификаторов в виде значений, разделенных запятыми - PullRequest
1 голос
/ 30 марта 2012

Как выбрать из базы данных все строки с идентификатором, хранящимся в запятой varchar. например, у меня есть таблица с этим:

, 7, 9, 11

Как я могу выбрать строки с этими идентификаторами?

Ответы [ 6 ]

4 голосов
/ 30 марта 2012

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

1 голос
/ 30 марта 2012

У вас есть 2 варианта:

  1. Используйте функцию, чтобы разбить строку на временную таблицу, а затем соединить выбранную вами таблицу с этой временной таблицей.
  2. Использовать динамический SQLзапросить таблицу с идентификатором в (@variable) --- неправильный выбор, если вы выберете этот способ.
0 голосов
/ 30 марта 2012

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

Отношения «многие ко многим» лучше всего представить тремя (3) таблицами.Допустим, вы продаете «виджеты» разных размеров.Создайте две таблицы, представляющие основные объекты:

Виджет (уникальные виджеты)

WidgetID | WidgetTitle
1        | Widget 1
2        | Widget 2
....

Размер (уникальные размеры)

SizeID  | SizeTitle
 7      | X-Small
 8      | Small
 9      | Medium
10      | Large
11      | X-Large

Затем создайте таблицу соединений для хранения связей между этими двумя объектами, т. е. какие виджеты доступны и в каких размерах

WidgetSize (доступные размеры для каждого виджета)

WidgetID | SizeID
1        | 7         <== Widget 1  "X-Small"
1        | 8         <== Widget 1 + "Small"
2        | 7         <== Widget 2 + "X-Small"
2        | 9         ....
2        | 10
2        | 11
....

С этой структурой вы можете легко вернуть все виджеты, имеющие какой-либо (или все) список размеров.Не проверено, но что-то похожее на sql ниже должно работать.

  • Поиск доступных виджетов в любых размеров: <cfset listOfSizes = "7,9,11">

     SELECT w.WidgetID, w.WidgetTitle
     FROM   Widget w 
     WHERE  EXISTS 
           (   SELECT 1 
               FROM   WidgetSize ws 
               WHERE  ws.WidgetID = w.WidgetID
               AND    ws.SizeID IN ( 
                       <cfqueryparam value="#listOfSizeIds#" 
                              cfsqltype="cf_sql_integer" list="true" > 
                      )
           )
    
  • Поиск доступных виджетов в все три размера: <cfset listOfSizes = "7,9,11">

      SELECT   w.WidgetID, w.WidgetTitle, COUNT(*) AS MatchCount
      FROM     Widget w INNER JOIN WidgetSize ws ON ws.WidgetID = w.WidgetID
      WHERE    ws.SizeID IN ( 
                       <cfqueryparam value="#listOfSizeIds#" 
                              cfsqltype="cf_sql_integer" list="true" > 
               )
      GROUP BY w.WidgetID, w.WidgetTitle
      HAVING   MatchCount = 3
    
0 голосов
/ 30 марта 2012

Буквально вчера я исправлял ошибку в старом приложении и видел, где они обрабатывали это так:

AND (T.ServiceIDs = '#SegmentID#' OR T.ServiceIDs LIKE '#SegmentID#,%'
                OR T.ServiceIDs LIKE '%,#SegmentID#,%' OR T.ServiceIDs LIKE '%,#SegmentID#')

Я предполагаю, что вы говорите что-то вроде значения ServiceID из базы данных, которое может содержать7,9,11 и что переменная SegmentID имеет одно или несколько значений.Это было в проверке оператора CFIF, чтобы увидеть, что SegmentID на самом деле имеет значение (которое всегда имело место из-за предыдущей логики, которая будет его использовать по умолчанию.

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

Мне пришлось решать эту проблему несколько лет назад, когда я не мог изменить таблицуструктура и я создал пользовательский тип таблицы и набор функций, чтобы я мог обрабатывать значения с помощью SQL, как если бы они пришли из таблицы. Это решение пользовательского типа таблицы, хотя и специфично для Oracle, и я не знаю, как это сделатьв MySQL без каких-либо исследований с моей стороны.

0 голосов
/ 30 марта 2012

Использовать совпадение (столбец) с ('7,9,11')

. Здесь будут показаны все столбцы varchar вашего идентификатора, где 7,9,11.Но вы должны быть уверены, что ваш столбец имеет полнотекстовый индекс.

0 голосов
/ 30 марта 2012
select * from table_name where id in (7, 9, 11)

Если у вас обычно есть эта запятая в начале, вам нужно сначала удалить ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...