2014-07-22 3 views
0

Je dois 3 tables:sorte MySQL de l'union

CREATE TABLE IF NOT EXISTS `Articles` (
    `id` int(11) NOT NULL DEFAULT '', 
    ... 
    ... 
    PRIMARY KEY (`id_article`) 
) ENGINE=InnoDB ; 

Persons_Articles:

CREATE TABLE IF NOT EXISTS `Persons_Articles` (
    `id_article` int(11) NOT NULL, 
    `id_person` int(11) UNSIGNED NOT NULL, 
    `role` TINYINT(4) UNSIGNED, 
    PRIMARY KEY (`id_article`,`id_person`,`role`) 
) ENGINE=InnoDB ; 

Personnes:

CREATE TABLE IF NOT EXISTS `Persons` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `firstname` varchar(64) DEFAULT NULL, 
    `lastname` varchar(64) NOT NULL, 
    `fullname` varchar(128) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB ; 

INSERT INTO Articles VALUES (1, 'A'), (2, 'B'), (3, 'B'); 
INSERT INTO Persons_Articles VALUES (1, 1, 1); 
INSERT INTO Persons_Articles VALUES (1, 2, 2); 
INSERT INTO Persons VALUES (1, 'Mick', 'Jagger', 'Mick Jagger'); 
INSERT INTO Persons VALUES (2, 'Keith', 'Richards', 'Keith Richards'); 

Je cherche une requête qui peut renvoyer l'article avec (fullname = 'Mick Jagger' ET rôle = 1) AND (nom complet = 'Keith Richards' ET rôle = 2)

Des idées?

+0

@Torrezzzz, votre commentaire suggère une réponse incorrecte. –

Répondre

1

Essayez de faire ce qui suit:

SELECT * FROM Persons P 
INNER JOIN Persons_Articles PA ON PA.id_person = P.id 
INNER JOIN Articles A ON A.id = PA.id_article 
WHERE (P.fullname = 'Mick Jagger' AND PA.role = 1) OR (P.fullname = 'Keith Richards' AND PA.role = 2) 
+1

Cette requête semble fonctionner ... Vous pouvez le vérifier ici: http://sqlfiddle.com/#!2/22ad0e/2 – lpg

+1

Je pense que le PO voulait l'article qui a ces deux personnes dans leurs rôles respectifs, pas non plus . – Arth

+0

@Ipg Vive le violon – Arth

1

Cela suppose que vous ne pouvez pas avoir ont un double (nom et rôle) pour un article:

SELECT a.* 
    FROM articles a 
    JOIN persons_articles pa 
     ON pa.id_article = a.id 
    JOIN persons p 
     ON pa.id_person = p.id 
    AND ((p.fullname = 'Mick Jagger' AND pa.role = 1) OR (p.fullname = 'Keith Richards' AND pa.role = 2)) 
GROUP BY a.id 
    HAVING count(*) = 2; 

MISE À JOUR

En côté note, je ne stockerais jamais le nom complet dans la base de données .. il conduit à plus de travail avec UPDATE s et INSERT s et si vous ne faites pas attention, vous pouvez vous retrouver avec des noms incompatibles. Bien que ce soit légèrement plus de travail, vous pouvez toujours les noms si besoin est.

+0

S'il vous plaît expliquer le vote vers le bas! – Arth

+0

Je viens de l'essayer avec mes vraies tables (70000 articles, 100000 personnes ...). Aucun résultat – Amoeba

+0

le prénom et le nom sont stockés depuis le début :-) – Amoeba