2010-10-27 5 views
1

Très bien, j'ai récemment commencé à normaliser ma base de données pour ce petit projet parallèle que je crée depuis un moment maintenant, mais je viens de frapper un mur de briques. Je vais essayer de donner un exemple compréhensible de ce que j'ai et de ce que j'ai besoin d'accomplir - et j'espère que ce ne sera pas trop douloureux. D'ACCORD.MySQL Advanced SELECT help

J'ai 3 tables le premier que nous appellerons Shows, structuré quelque chose comme ceci:

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

pure et simple.

Ma prochaine table est appelée Catégories et lookes comme ceci:

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

et une table finale appelée Show_categories:

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

Comme vous avez sans doute remarqué le problème est dans ma base de données une seul spectacle peut avoir plusieurs catégories. Tout est bien structuré, sauf le fait que je ne peux pas trouver un pourquoi chercher un spectacle avec plusieurs catégories. Si je devais rechercher des spectacles de type action et comédie, on me donnerait l'exemple n ° 1, mais ce n'est pas possible (du moins avec mes requêtes), car les cat_id à l'intérieur des Show_categories sont dans des rangées différentes.

Exemple d'une recherche sur une seule catégorie de travail (Sélection de tous les spectacles de comédie):

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 

Et une requête qui est impossible (parce que cat_id ne peut pas égaler 2 choses différentes):

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 

Donc, pour résumer ce que je demande est comment puis-je gérer une requête où je suis à la recherche d'un spectacle basé sur plusieurs catégories correspondantes.

Répondre

4

Utilisation:

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 

Les besoins de comparaison COUNT(DISTINCT sc.cat_id) égal au nombre de valeurs cat_id répertoriées dans la clause IN. Mais si les colonnes SHOW_CATEGORIES show_id et cat_id sont toutes deux la clé primaire, ou s'il existe une contrainte unique sur les deux colonnes, vous pouvez utiliser COUNT(sc.cat_id).

+0

cela pourrait échouer si la base de données n'est pas configurée correctement et permet le même enregistrement deux fois dans la table 'show_categories' – cambraca

+0

@cambraca: Non - J'ai expliqué le besoin de COUNT DISTINCT s'il y a un risque de doublons. –

+0

C'est ainsi que je l'ai mis en place, et la requête a fonctionné parfaitement. – ahoka

0

Vous avez besoin d'une instruction 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 

C'est, vous voulez tous les spectacles soit catid 1 OU catid 2. Donc, cette requête retourne 1, 2 et 3.

+0

Que faire si un spectacle a deux associations à cat_id "1" mais aucune association à cat_id "2"? –

+1

Si la base de données est correctement normalisée, elle ne devrait pas avoir 2 associations avec catid 1. Il n'y a aucune raison de dire qu'une émission appartient deux fois à la catégorie comédie. –

+0

Cela retournera les spectacles qui sont soit OU, j'ai besoin de faire correspondre les spectacles qui sont à la fois cat_id = 1 et cat_id = 2. – ahoka