sql запрос — правильный способ получить идентификатор из строки?

#sql

#sql

Вопрос:

У меня есть таблица customer, в которой есть поле «категории». Это строка, содержащая идентификаторы, разделенные запятыми типа 1,11,14,21 .

Допустим, я хочу запросить всех клиентов, у которых есть CategoryID 1 — какой правильный способ запросить это?

Проблема в том, что идентификатор 1 может находиться в начале, середине или конце строки или даже быть единственным идентификатором, поэтому мне пришлось бы охватывать все случаи, такие как:

 WHERE categories LIKE '1' 
   OR categories LIKE '1%,' 
   OR categories LIKE '%,1,%' 
   OR categories like '%,1'
  

Есть ли более элегантный (и, вероятно, намного более быстрый) способ сделать это?

Комментарии:

1. Для какой базы данных? Реальное решение состоит в том, чтобы не хранить информацию подобным образом и использовать правильную настройку таблицы «многие ко многим».

Ответ №1:

Вместо этого у вас должна быть таблица CustomerCategories, в которой есть столбцы CustomerID, CategoryID, а затем по одной записи для каждой категории клиентов. Это намного проще для запроса — и в высшей степени является нормой для реляционных баз данных.

Хранение массивов идентификаторов в строках нереляционно и, как вы обнаружили, является кошмаром для запроса.

Комментарии:

1. Даже не «намного больше нормы», скорее «норма».

Ответ №2:

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

На этой ноте, я думаю, это будет подходящим обходным путем для вас.

 WHERE ',' [categories] ',' LIKE '%,1,%'
  

Комментарии:

1. Медленно, из-за отсутствия какого-либо индекса.

2. @Amadan: О, я уверен, что это особенно неэффективно… но таков и способ хранения данных.

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