2010-10-27 3 views
1

Хорошо, что недавно я начал нормализовать свою базу данных для этого небольшого проекта, который я создавал какое-то время, но я только что ударил по кирпичной стене. Я попытаюсь дать понятный пример того, что у меня есть и что мне нужно сделать - и, надеюсь, это будет не слишком болезненно. ОК.MySQL Advanced SELECT help

У меня есть 3 таблицы первый, который мы будем называть шоу, структурирована что-то вроде этого:

+----+--------------------------+ 
| id | title     | 
+----+--------------------------+ 
| 1 | Example #1    | 
| 2 | Example #2    | 
| 3 | Example #3    | 
+----+--------------------------+ 

равнины и простой.

Моя следующая таблица называется Категории и lookes как это:

+----+--------------------------+ 
| id | category     | 
+----+--------------------------+ 
| 1 | Comedy     | 
| 2 | Drama     | 
| 3 | Action     | 
+----+--------------------------+ 

И финальный стол под названием Show_categories:

+---------+---------+ 
| show_id | cat_id | 
+---------+---------+ 
| 1  |  1 | 
| 1  |  3 | 
| 2  |  2 | 
| 2  |  3 | 
| 3  |  1 | 
| 3  |  2 | 
+---------+---------+ 

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

Если бы я искал шоу типа действия и комедии, мне бы дали пример №1, но это невозможно (по крайней мере, с моими запросами), потому что cat_id внутри Show_categories находятся в разных строках.

Пример рабочего один поиск категории (Выбор всех комедийных шоу):

SELECT s.id,s.title 
    FROM Shows s JOIN Show_categories sc ON sc.anid=s.id 
    WHERE sc.cat_id=1 GROUP BY s.id 

И запрос, который невозможно (так как cat_id не может равняться 2 разные вещи):

SELECT s.id,s.title 
    FROM Shows s JOIN Show_categories sc ON sc.anid=s.id 
    WHERE sc.cat_id=1 AND sc.cat_id=2 GROUP BY s.id 

Итак, чтобы подвести итог тому, что я спрашиваю, как обрабатывать запрос, где я ищу шоу, основанное на нескольких подходящих категориях.

ответ

4

Использование:

SELECT s.id, 
     s.title 
    FROM SHOWS s 
    JOIN SHOW_CATEGORIES sc ON sc.anid = s.id 
    WHERE sc.cat_id IN (1, 2) 
GROUP BY s.id, s.title 
    HAVING COUNT(DISTINCT sc.cat_id) = 2 

The COUNT(DISTINCT sc.cat_id) потребности сравнения чтобы равняться числу значений cat_id, перечисленных в предложении IN. Но если оба столбца SHOW_CATEGORIES являются либо первичным ключом, либо существует уникальное ограничение для обоих столбцов, то вы можете использовать COUNT(sc.cat_id).

+0

это может завершиться неудачно, если db не настроен должным образом и позволяет одну и ту же запись дважды в таблице show_categories – cambraca

+0

@cambraca: Нет. Я объяснил необходимость в COUNT DISTINCT, если есть вероятность дублирования. –

+0

Вот как я его настроил, и запрос работал идеально. – ahoka

0

Вам понадобится инструкция OR.

SELECT s.id,s.title 
    FROM Shows s JOIN Show_categories sc ON sc.anid=s.id 
    WHERE sc.cat_id=1 OR sc.cat_id=2 GROUP BY s.id 

То есть, вы хотите, чтобы все шоу либо CatID 1 ИЛИ CatID 2. Таким образом, этот запрос будет возвращать 1, 2 и 3.

+0

Что делать, если шоу имеет две ассоциации с cat_id "1", но нет ассоциаций с cat_id "2"? –

+1

Если база данных правильно нормализована, она не должна иметь 2 ассоциации с catid 1. Нет причин говорить, что шоу относится к категории комедий дважды. –

+0

Это вернет шоу, которые являются либо ИЛИ, мне нужно сопоставить шоу, которые являются cat_id = 1 и cat_id = 2. – ahoka