这可能很简单,但是找不到正确的搜索词,因此,如果重复搜索,就很可能会在某个地方找到答案。
我设置了以下表格
CREATE TABLE IF NOT EXISTS `customer` (
`id` int(6) unsigned auto_increment NOT NULL,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `billing_run` (
`id` int(6) unsigned auto_increment NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `invoice` (
`id` int(6) unsigned auto_increment NOT NULL,
`billing_run_id` int(6) unsigned NOT NULL,
`customer_id` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (billing_run_id) REFERENCES billing_run(id),
FOREIGN KEY (customer_id) REFERENCES customer(id)
) DEFAULT CHARSET=utf8;
具有以下数据
insert into customer (name) values ('test customer');
insert into billing_run (date) values ('2019-01-01 12:00:00');
insert into billing_run (date) values ('2019-02-01 12:00:00');
insert into billing_run (date) values ('2019-03-01 12:00:00');
insert into invoice (customer_id,billing_run_id) values (1,1);
SQLFiddle此处-> http://sqlfiddle.com/#!9/a54162/5
我想获取customer
与invoice
相关且billing_run
为2的id
不相关的记录
我的查询
select c.id from customer c
left join invoice i on i.customer_id = c.id
left join billing_run br on br.id = i.billing_run_id and br.id = 2
where i.id is null
返回0条记录。为什么?
答案 0 :(得分:1)
首先,将表customer
(1行)与表invoice
(1行)连接。
此联接将返回1行,因为ON
子句中的列之间存在匹配项:
on i.customer_id = c.id
(示例数据中i.customer_id
和c.id
的值均为1
)。
因此,i.id is null
没有任何行。
表billing_run
的下一个联接不影响前2个联接的表。
所以条件:
where i.id is null
不返回任何行。
正确的条件(您在原始小提琴中具有的条件)是:
where br.id is null
因为对表billing_run
的联接将为该条件返回不匹配的行:
on br.id = i.billing_run_id and br.id = 2
因为i.billing_run_id = 2
中没有invoice
。
答案 1 :(得分:1)
您将要执行一个排他的where子句,该子句将返回所需的1行。
select * from customer c
where c.id not in (Select customer_id from invoice i LEFT JOIN billing_run br on
i.billing_run_id=br.id WHERE br.id=2 and br.id is not null)
答案 2 :(得分:0)
您不需要billing_run
表。所以我认为您打算:
select c.id
from customer c left join
invoice i
on i.customer_id = c.id and i.billing_run_id = 2
where i.id is null