2008-10-16 4 views
8

Dans la suivante à plusieursSQL one-to-many correspondance d'un côté par ALL dans de nombreux côté

CREATE TABLE source(id int, name varchar(10), PRIMARY KEY(id)); 
CREATE TABLE params(id int, source int, value int); 

où params.source est une clé étrangère à source.id

INSERT INTO source values(1, 'yes'); 
INSERT INTO source values(2, 'no'); 

INSERT INTO params VALUES(1,1,1); 
INSERT INTO params VALUES(2,1,2); 
INSERT INTO params VALUES(3,1,3); 

INSERT INTO params VALUES(4,2,1); 
INSERT INTO params VALUES(5,2,3); 
INSERT INTO params VALUES(6,2,4); 

Si j'ai une liste de valeurs param (disons [1,2,3]), comment trouver toutes les sources qui ont TOUTES les valeurs dans la liste (source 1, "oui") en SQL?

Merci

+0

J'espère que quelqu'un d'autre comprend mieux que moi ... vous pourriez envisager de le reformuler. – Greg

Répondre

7

Modifier modifié pour gérer les cas où il peut y avoir plusieurs occurrences de la valeur pour une source donnée.

Essayez ceci:

SELECT 
    * 
FROM 
    source 
WHERE 
    (
     SELECT COUNT(DISTINCT value) 
     FROM params 
     WHERE params.source = source.id 
      AND params.value IN (1, 2, 3) 
    ) = 3 

Vous pouvez réécrire un GROUP BY ainsi:

SELECT 
    source.* 
FROM 
    source 
    INNER JOIN params ON params.source = source.id 
WHERE 
    params.value IN (1, 2, 3) 
GROUP BY 
    source.id, 
    source.name 
HAVING 
    COUNT(DISTINCT params.value) = 3 
+0

J'irais définitivement pour le groupe par la syntaxe. Beaucoup plus expressif et moins douloureux à regarder. – Tomalak

+0

Et s'il y avait plus d'un enregistrement dans params avec la même valeur pour la même source? –

+0

c'est une bonne question Russ. Je suppose que James doit nous dire si c'est vrai ou non. –

11
SELECT s.* 
FROM source AS s 
JOIN params AS p ON (p.source = s.id) 
WHERE p.value IN (1,2,3) 
GROUP BY s.id 
HAVING COUNT(DISTINCT p.value) = 3; 

Vous devez le DISTINCT parce que votre params.value est pas empêchée d'avoir des doublons .

+0

Ce fut le plus élégant, avant lassevk mis en œuvre le même :) –