2012-03-30 6 views
1

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

, 7, 9, 11 

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

+5

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

+2

Производительность также будет проблемой. Это НЕ, как вы должны хранить данные в базе данных. – datagod

+0

Это также больше подвержено ошибкам. Если вы храните целые числа, результаты всегда будут одинаковыми. Но при сохранении строк поиск «7» не даст того же значения, что и «7.0» или даже «7 (пробел)». +1 для нормализации таблиц. – Leigh

ответ

0
select * from table_name where id in (7, 9, 11) 

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

+1

Это не сработает - он хранит идентификаторы CSV в одном столбце. –

+1

Совершенно неправильно. csvs находятся в Varchar. – shashankaholic

+0

Как указано, это не будет работать из-за того, как данные хранятся. –

1

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

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

Используйте матч (столбец) против ('7,9,11')

это Willl показать все VARCHAR столбец ваших идентификаторов, где 7,9,11 есть. Но вы должны быть уверены, что в столбце ur есть полный текст.

+0

Что происходит, когда вы ищете (9, 7, 11) в этом случае? –

+0

тот же результат, что и матч против совпадений каждой отдельной запятой. –

3

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

+0

Не знаете, что именно вы понимаете под поисковой таблицей. – Computerman1597

+3

у вас должна быть таблица с ссылкой на PK и строка для каждого отдельного значения, которое вы указали выше. 7,9,11 следует указывать в виде трех отдельных записей в базе данных (в другой таблице) –

0

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

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

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

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

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

0

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

Many-to-many отношения лучше всего представлены тремя (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 
    
Смежные вопросы