试试这个:
SQL Fiddle
PostgreSQL 9.3 架构设置:
BEGIN;
-- DROP TABLE IF EXISTS customer;
-- DROP TABLE IF EXISTS vehicle;
-- DROP TABLE IF EXISTS testdrive;
CREATE TABLE customer (
id SERIAL PRIMARY KEY,
email TEXT
);
CREATE TABLE vehicle (
id SERIAL PRIMARY KEY,
modelname TEXT
);
CREATE TABLE testdrive (
id SERIAL PRIMARY KEY,
vehicle_id INTEGER REFERENCES vehicle(id),
customer_id INTEGER REFERENCES customer(id)
);
INSERT INTO customer (email) VALUES
('Bob@foo.org'), ('Alice@bar.net'), ('Mary@baz.com'),
('Fred@int.edu'), ('Joe@mut.var');
INSERT INTO vehicle (modelname) VALUES ('Camry'), ('Accord');
INSERT INTO testdrive (vehicle_id, customer_id)
VALUES
(1, 1), -- Camry, Bob
(1, 2), -- Camry, Alice
(2, 1), -- Accord, Bob
(2, 3); -- Accord, Mary
-- Fred and Joe never test drove anything.
-- Mary didn't test drive the Camry.
-- Alice didn't test drive the Accord.
-- How do I query to find the list of customers who didn't test
-- drive anything, for each vehicle model?
-- Customers who didn't test drive the Camry:
-- Mary, Fred, Joe
SELECT c.email
FROM customer AS c
LEFT JOIN testdrive AS t ON c.id=t.customer_id
LEFT JOIN vehicle AS v ON t.vehicle_id=v.id AND v.modelname='Camry'
WHERE v.id IS NULL;
-- Customers who didn't test drive the Accord:
-- Alice, Fred, Joe
COMMIT;
查询 1:
SELECT *
FROM customer c
WHERE NOT EXISTS
( SELECT *
FROM testdrive t
INNER JOIN vehicle v
on v.id = t.vehicle_id
WHERE v.modelname = 'Camry' AND t.customer_id = c.id)
Results:
| id | email |
|----|--------------|
| 3 | Mary@baz.com |
| 4 | Fred@int.edu |
| 5 | Joe@mut.var |
查询 2:
SELECT *
FROM customer c
WHERE NOT EXISTS
( SELECT *
FROM testdrive t
INNER JOIN vehicle v
on v.id = t.vehicle_id
WHERE v.modelname = 'Accord' AND t.customer_id = c.id)
Results:
| id | email |
|----|---------------|
| 2 | Alice@bar.net |
| 4 | Fred@int.edu |
| 5 | Joe@mut.var |