2011-01-12 3 views
0

Я работаю над небольшим проектом, который включает в себя захват списка контактов, которые хранятся для каждой группы. По существу, база данных настроена таким образом, чтобы каждая группа имела первичный и вторичный контакты, которые были сохранены, как неудивительно, Group.Primary и Group. Secondary. Цель состоит в том, чтобы вытащить каждый первичный и вторичный контакт для каждой группы и отобразить их в сортируемой таблице.MySQL Query Where Column Like Column

У меня есть сортируемый стол, все получилось, но я столкнулся с небольшой проблемой. Каждое первичное и вторичное поле может содержать более одного контакта, разделенных запятой. Например, если Primary содержал 123,256, то ему необходимо будет тянуть как контакты с идентификаторами 123 и 256. Я намеревался использовать запрос, отформатированный как это:

SELECT * 
    FROM Group G, 
     Contacts C 
WHERE G.Primary LIKE %C.ID% 
    OR G.Secondary LIKE %C.ID% 

, так что я мог бы просто пропустить запятую часть, но Кажется, я не могу найти рабочий запрос.

Мой вопрос к вам: я просто что-то пропустил? Есть ли простой запрос, который позволил бы мне это сделать? Или мне лучше получить группы и контакты по отдельности, и объединить их позже. Я думаю, что первое немного легче понять при чтении, что является плюсом, поскольку это общий проект, но если это невозможно, я сделаю последнее.

Этот код упрощен, но он имеет точку пересечения.

+0

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

+0

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

ответ

3

Если я правильно понимаю, вы хотите использовать MySQL FIND_IN_SET function:

SELECT * 
    FROM Group G 
    JOIN Contacts C ON FIND_IN_SET(c.id, g.primary) 
        OR FIND_IN_SET(c.id, g.secondary) 

Но я настоятельно рекомендую вам нормализовать таблицу - не храним запятыми список, если это вообще возможно.

+0

Это сделало трюк, большое спасибо! – shmeeps

0

Я думаю, что вам определенно лучше отделить эти два значения данных от разных таблиц, а затем использовать JOIN s, чтобы сделать вашу ссылку. Если бы вы, скажем, отбросили свои поля id к строкам, чтобы вы могли использовать сравнение LIKE, вы получите кучу нежелательных совпадений. Например, если ваш основной идентификатор 1, а ваш вторичный является 35, то вы бы соответствовать на следующий (и этот список не является исчерпывающим):

1: 1, 2: 35 
1: 35, 2: 1 
1: 10, 2: 135 
1: 431, 2: 3541 

т.д.

Что я бы делать вместо этого что-то вроде этого:

SELECT * 
FROM Group G 
LEFT JOIN Contacts c1 on g.primary = c1.id 
LEFT JOIN Contacts c2 on g.secondary = c2.id 
WHERE 
c1.id IS NOT NULL 
OR 
c2.id IS NOT NULL 

Я думаю, что получите вам данные, вы действительно ищете, если я понимаю вопрос правильно.

0

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

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

Если вы не можете этого сделать, вам нужно разработать алгоритм соответствия строк, который всегда будет работать. Проблема с той, которую вы предложили, заключается в том, что вам необходимо рассмотреть идентификатор контакта 23 (или даже 3), который будет соответствовать 23, 123, 223, 231 и т. Д. Чтобы выполнить эту работу, вам нужно добавить запятую в начало и конец обеих строк, которые вы сравниваете, а затем сделать LIKE.

К сожалению.Или вы можете использовать ранее известную функцию FIND_IN_SET, описанную выше, Ponies.

+0

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