在此处扩展此问题:Efficient way to select records missing in another table,说我有以下3个表格(原始示例,请参阅下面的更好示例):
request: (id, name)
response: (id, request_id, provider_id, resource)
provider: (id, name)
首先,我想检索所有不存在结果的请求。这很简单,使用LEFT JOIN
。我还想要任何未针对给定requests
执行的provider
。 用简单的英语:我希望所有没有结果的请求或只有其他提供商的结果。
这是一个更好的例子:
customer: (id, email)
vehicle: (id, modelname)
testdrive: (id, vehicle_id REFERENCES vehicle(id), customer_id REFERENCES customer(id)
说鲍勃,爱丽丝,玛丽,弗雷德和乔访问汽车经销商。鲍勃和爱丽丝试驾凯美瑞,鲍勃和玛丽试驾雅阁,弗雷德和乔没有试驾任何东西。经销商希望制作两份清单:
这是一个SQL小提琴演示:http://sqlfiddle.com/#!15/80d6a
以下是建议的,但它不太正确(参见上面的SQL Fiddle链接),因为它还为我提供了DID测试驾驶OTHER车型的人:
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;
答案 0 :(得分:1)
SELECT c.email
FROM customer AS c
WHERE NOT c.customer_ID IN (SELECT customer_id FROM testdrive WHERE vehicle_id=@Camry);
答案 1 :(得分:1)
试试这个:
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 |