Question

There are tables with clients and festivals. Every festival happens every year (like New Year). But not every client is invited on any festival.

I need to get woman clients, that were invited on festival1 at this moment, but weren't invited on festival2.

Table "clients"
+-----+--------------+-----------+---------+-----+
| id  | name         | email     | adress  | sex |
+-----+--------------+-----------+---------+-----+
| 1   | Ivan         | iva@ya.su | NY city | m   |
| 2   | Michael      | lad@ya.su | LA      | m   |
| 3   | Anna         | al@ya.su  | 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 |
| ...
+--------+----------+

I started to do something like this query, but it need to be corrected:

SELECT name
    FROM clients, festivals, invitations
    WHERE clients.sex = w
        AND festivals.name = festival1
        AND clients.id = invitations.client
        AND invitations.year = 2013
Was it helpful?

Solution

You can use NOT EXISTS to eliminate results from your query:

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

OTHER TIPS

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

I would do something like this:

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'

First you need to join clients with festivals through: clients/invitations then invitations/festivals

Second you need to discard clients invited to 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top