2013-06-14 4 views
1

Il existe des tables avec des clients et des festivals. Chaque festival a lieu chaque année (comme le Nouvel An). Mais tous les clients ne sont pas invités à un festival.Plusieurs tables de sélection SQL

J'ai besoin de clients féminins, qui ont été invités sur festival1 en ce moment, mais qui n'ont pas été invités sur festival2.

Table "clients" 
+-----+--------------+-----------+---------+-----+ 
| id | name   | email  | adress | sex | 
+-----+--------------+-----------+---------+-----+ 
| 1 | Ivan   | [email protected] | NY city | m | 
| 2 | Michael  | [email protected] | LA  | m | 
| 3 | Anna   | [email protected] | LA  | w | 
| ... 
+-----+--------------+-----------+---------+-----+ 

Table festivals 
+-----+------------+-------+ 
| id | name  | date | 
+-----+------------+-------+ 
| 1 | festival1 | 8-03 | 
| 2 | festival2 | 23-02 | 
| 3 | festival3 | 1-01 | 
| ... 
+-----+------------+-------+ 

Talbe "invitations" 
+--------+----------+------+ 
| client | festival | year | 
+--------+----------+------+ 
| 1  | 2  | 2013 | 
| 3  | 1  | 2009 | 
| ... 
+--------+----------+ 

j'ai commencé à faire quelque chose comme cette requête, mais il est nécessaire de corriger:

SELECT name 
    FROM clients, festivals, invitations 
    WHERE clients.sex = w 
     AND festivals.name = festival1 
     AND clients.id = invitations.client 
     AND invitations.year = 2013 
+0

Pouvez-vous être plus précis sur ce que est faux avec votre requête? Qu'attendiez-vous et qu'as-tu obtenu à la place? –

+0

Non lié, mais bien que la syntaxe de jointure que vous utilisez ne soit pas fausse, elle est obsolète depuis plus de 20 ans et a été remplacée dans ANSI 92 par des jointures explicites. Aaron Bertrand a fait un bien meilleur cas que je pourrais ici pour passer à la nouvelle syntaxe de jointure http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old -style-joins.aspx – GarethD

Répondre

1

Vous pouvez utiliser NOT EXISTS pour éliminer les résultats de votre recherche:

SELECT * 
FROM Clients 
     INNER JOIN Invitations 
      ON Invitations.Client = Clients.ID 
     INNER JOIN Festivals 
      ON Festivals.ID = Invitations.Festival 
WHERE Festivals.Name = 'Festival1' 
AND  Clients.Sex = 'W' 
AND  Invitations.Year = 2013 
AND  NOT EXISTS 
     ( SELECT 1 
      FROM Invitations i2 
        INNER JOIN Festivals f2 
         ON f2.ID = i2.Festival 
      WHERE i2.Client = Clients.ID 
      AND  f2.Name = 'Festival2' 
      AND  i2.Year = Invitations.Year 
     ); 

Example on SQL Fiddle

1
SELECT c.name 
FROM clients c 
INNER JOIN invitations i ON c.id = i.client 
INNER JOIN festivals f ON f.id = i.festival 
WHERE c.sex = 'w' 
AND i.year = 2013 
group by c.name 
having sum(case when f.name='festival1' then 1 else 0 end) > 0 
and sum(case when f.name='festival2' then 1 else 0 end) = 0 
1

je ferais quelque chose comme ceci:

SELECT c.Name 
    FROM clients c 
    INNER JOIN invitations i 
     ON i.client = c.id 
     AND i.year = 2013 
    INNER JOIN festivals f 
     ON i.festival = f.id 
     AND f.name = 'festival1' 
WHERE 
    c.sex = 'w' 
+0

merci pour votre réponse. mais cette requête prendra aussi des femmes invitées ou non invitées sur festival2. Je n'ai besoin que de ne pas avoir été invité sur festival2. – sirjay

0

Tout d'abord vous avez besoin pour rejoindre des clients avec des festivals à travers: clients/invitations puis invitations/festivals

Ensuite, vous devez jeter les clients invités à festival2

SELECT name 
    FROM clients, festivals, invitations 
    WHERE clients.sex = w 
     AND festivals.name = festival1 
     AND festivals.name != festival2 
     AND clients.id = invitations.client 
     AND festivals.id = invitations.festival 
     AND invitations.year = 2013