SELECT
b.BusinessId,
b.BusinessName
FROM
tblBusiness AS b
INNER JOIN tblBusinessTagLink AS l ON l.BusinessId = b.BusinessId
INNER JOIN tblTags AS t ON t.TagId = l.TagId
WHERE
t.TagName IN ('Technology', 'Office Supplies')
GROUP BY
b.BusinessId,
b.BusinessName
Это выбирает все предприятия, которые входят в одну из категорий.Чтобы выбрать только те, которые в обеих категориях, вы можете добавить
HAVING COUNT(*) = 2
Метод, который вы используете (три таблицы для представления отношения am: n), является стандартным способом решения этой задачи, вы можете оставить его.
Лично я бы не использовал «венгерскую нотацию» для имен таблиц (т.е. без «tbl») и не использовал бы имена таблиц во множественном числе (т.е. не «теги»), особенно когда другие таблицы не являются множественными.Либо.
Отвечая на первый комментарий ниже:
Для больших наборов данных производительность этого запроса зависит от индексов.Все первичные ключи нуждаются в индексе, естественно.В tblBusinessTagLink
у вас должен быть составной индекс, охватывающий оба поля, и один дополнительный индекс для поля, которое не стоит на первом месте в составном индексе.
Идея WHERE keywords LIKE '%technology%'
плохая, главным образом потому, что для любогоКак условия, отличные от поиска по полю, индекс не может быть использован (т. Е. Производительность будет быстро снижаться по мере роста набора данных), так как отчасти это должно быть WHERE ','+keywords+',' LIKE '%,technology,%'
для начала, иначе вы получите частичные совпадения / ложные срабатывания.
Кроме того, запрос может быть более эффективным по TagId
.Таким образом, вы можете полностью удалить одну таблицу из JOIN:
FROM
tblBusiness AS b
INNER JOIN tblBusinessTagLink AS l ON l.BusinessId = b.BusinessId
WHERE
l.TagId IN (1, 2)
Если вы намереваетесь выполнить запрос по TagName
, индекс в этом поле также будет абсолютно необходим.