Search code examples
mysqlsqlrelational-division

Write a query that can show which parties have candidates in all districts?


So I have created 3 tables with values

#Creating parties table

DROP TABLE IF EXISTS parties,districts,candidates;
CREATE TABLE parties ( party char(12) NOT NULL, PRIMARY KEY (party) );
INSERT INTO parties VALUES ('Conservative'),('Liberal'), ('Socialist'),('Green'),('Libertarian');

#Creating districts table

CREATE TABLE districts ( district char(10) DEFAULT NULL );
INSERT INTO districts VALUES ('Essex'), ('Malton'),('Riverdale'),('Guelph'),('Halton');

#Creating candidates table

CREATE TABLE candidates ( id int(11) NOT NULL, name char(10) DEFAULT NULL, district char(10) DEFAULT NULL, party char(10) DEFAULT NULL, PRIMARY KEY (id) ); 
INSERT INTO candidates VALUES (1,'Anne Jones','Essex','Liberal'), (2,'Mary Smith','Malton','Liberal'), (3,'Sara Black','Riverdale','Liberal'), (4,'Paul Jones','Essex','Socialist'), 
(5,'Ed White','Essex','Conservative'), (6,'Jim Kelly','Malton','Liberal'), (7,'Fred Price','Riverdale','Socialist'), (8,'Bill Green','Guelph','Green'), 
(9,'Garth Adams','Halton','Libertarian'), (10,'Sam Adams','Guelph','Liberal'), (11,'Jill Mackay','Halton','Liberal');

Now I want to find out which parties have candidates in all districts?

I have done this but I am not sure if this is the right way!! Can someone guide me?

select p.party 
from parties p 
    inner join candidates c on p.party = c.party
    inner join districts d on c.district = d.district;

Solution

  • You can use aggregation. Then use having to count the number of districts and see if all are included:

    select p.party
    from parties p inner join
         candidates c
         on p.party = c.party
    group by p.party
    having count(distinct district) = (select count(*) from districts);
    

    The count(distinct) handles the situation where a party has more than one candidate in a district.