Select Mysql 加入时值为空
Select Mysql with empty value on join
我有以下 MySQL 个表(创建和插入):
CREATE TABLE IF NOT EXISTS `department` (
`id` INT NOT NULL,
`name` VARCHAR(45) NOT NULL,
`father` INT NULL,
PRIMARY KEY (`id`),
INDEX `fk_department_department_idx` (`father` ASC) VISIBLE,
CONSTRAINT `fk_department_department`
FOREIGN KEY (`father`)
REFERENCES `department` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `print` (
`id` INT NOT NULL,
`page` INT NOT NULL,
`copy` INT NOT NULL,
`date` DATE NOT NULL,
`department` INT NULL,
PRIMARY KEY (`id`),
INDEX `fk_print_department1_idx` (`department` ASC) VISIBLE,
CONSTRAINT `fk_print_department1`
FOREIGN KEY (`department`)
REFERENCES `department` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
insert into department (id,name,father)
values
(1, 'dp1',null),
(2, 'dp2',null),
(3, 'dp3',1),
(4, 'dp4',2);
insert into print (id,page,copy,date,department)
values
(1,2,3,'2020-1-11',1),
(2,1,6,'2020-1-12',4),
(3,1,6,'2020-1-12',1),
(4,4,5,'2020-1-13',null),
(5,5,3,'2020-1-15',null),
(6,3,4,'2020-1-15',1),
(7,3,4,'2020-1-15',1),
(8,2,2,'2020-1-16',4);
我得到的最接近的是以下查询。
select
d.name as department,
f.name as father,
sum_print as sum
from
department d
left join department f on f.id = d.father
left join
(
select
department,
sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE)
AND CAST('2020-1-15' AS DATE)
group by department
) as tmp on tmp.department = d.id;
我得到的结果是。
| department | father | sum |
| dp1 | null | 24 |
| dp2 | null | null |
| dp3 | dp1 | null |
| dp4 | dp2 | null |
我需要的是以下内容。
| department | father | sum |
| dp1 | null | 24 |
| dp2 | null | null |
| dp3 | dp1 | null |
| dp4 | dp2 | null |
| null | null | 35 |
由于某种我无法理解的原因,我遗漏了最后一个元组。我想是因为这个 join as tmp on tmp.department = d.id
关注fiddle任何想使用它和/或可以提供帮助的人:Fiddle
我尝试了以下帖子,但没有成功。我现在卡住了。
- mysql-select-join-with-empty-row-returns
- mysql-inner-join-with-possible-empty-fields
您实际需要的是 2 个查询的完整外部联接。
问题是MySql(仍然)不支持这种join,所以必须用left和right join and union all来模拟:
with
d as (
select d.id, d.name as department, f.name as father
from department d left join department f
on f.id = d.father
),
p as (
select department, sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE) AND CAST('2020-1-15' AS DATE)
group by department
)
select d.department, d.father, p.sum_print
from d left join p
on p.department = d.id
union all
select d.department, d.father, p.sum_print
from d right join p
on p.department = d.id
where d.id is null
参见demo。
结果:
> department | father | sum_print
> :--------- | :----- | --------:
> dp1 | null | 24
> dp2 | null | null
> dp3 | dp1 | null
> dp4 | dp2 | null
> null | null | 35
这会给你想要的外连接结果
select
d.name as department,
f.name as father,
sum_print as sum
from
department d
left join department f on f.id = d.father
left join
(
select
department,
sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE)
AND CAST('2020-1-15' AS DATE)
group by department
) as tmp on tmp.department = d.id
UNION
select
d.name as department,
f.name as father,
sum_print as sum
from
department d
left join department f on f.id = d.father
right join
(
select
department,
sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE)
AND CAST('2020-1-15' AS DATE)
group by department
) as tmp on tmp.department = d.id;
我有以下 MySQL 个表(创建和插入):
CREATE TABLE IF NOT EXISTS `department` (
`id` INT NOT NULL,
`name` VARCHAR(45) NOT NULL,
`father` INT NULL,
PRIMARY KEY (`id`),
INDEX `fk_department_department_idx` (`father` ASC) VISIBLE,
CONSTRAINT `fk_department_department`
FOREIGN KEY (`father`)
REFERENCES `department` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `print` (
`id` INT NOT NULL,
`page` INT NOT NULL,
`copy` INT NOT NULL,
`date` DATE NOT NULL,
`department` INT NULL,
PRIMARY KEY (`id`),
INDEX `fk_print_department1_idx` (`department` ASC) VISIBLE,
CONSTRAINT `fk_print_department1`
FOREIGN KEY (`department`)
REFERENCES `department` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
insert into department (id,name,father)
values
(1, 'dp1',null),
(2, 'dp2',null),
(3, 'dp3',1),
(4, 'dp4',2);
insert into print (id,page,copy,date,department)
values
(1,2,3,'2020-1-11',1),
(2,1,6,'2020-1-12',4),
(3,1,6,'2020-1-12',1),
(4,4,5,'2020-1-13',null),
(5,5,3,'2020-1-15',null),
(6,3,4,'2020-1-15',1),
(7,3,4,'2020-1-15',1),
(8,2,2,'2020-1-16',4);
我得到的最接近的是以下查询。
select
d.name as department,
f.name as father,
sum_print as sum
from
department d
left join department f on f.id = d.father
left join
(
select
department,
sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE)
AND CAST('2020-1-15' AS DATE)
group by department
) as tmp on tmp.department = d.id;
我得到的结果是。
| department | father | sum |
| dp1 | null | 24 |
| dp2 | null | null |
| dp3 | dp1 | null |
| dp4 | dp2 | null |
我需要的是以下内容。
| department | father | sum |
| dp1 | null | 24 |
| dp2 | null | null |
| dp3 | dp1 | null |
| dp4 | dp2 | null |
| null | null | 35 |
由于某种我无法理解的原因,我遗漏了最后一个元组。我想是因为这个 join as tmp on tmp.department = d.id
关注fiddle任何想使用它和/或可以提供帮助的人:Fiddle
我尝试了以下帖子,但没有成功。我现在卡住了。
- mysql-select-join-with-empty-row-returns
- mysql-inner-join-with-possible-empty-fields
您实际需要的是 2 个查询的完整外部联接。
问题是MySql(仍然)不支持这种join,所以必须用left和right join and union all来模拟:
with
d as (
select d.id, d.name as department, f.name as father
from department d left join department f
on f.id = d.father
),
p as (
select department, sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE) AND CAST('2020-1-15' AS DATE)
group by department
)
select d.department, d.father, p.sum_print
from d left join p
on p.department = d.id
union all
select d.department, d.father, p.sum_print
from d right join p
on p.department = d.id
where d.id is null
参见demo。
结果:
> department | father | sum_print
> :--------- | :----- | --------:
> dp1 | null | 24
> dp2 | null | null
> dp3 | dp1 | null
> dp4 | dp2 | null
> null | null | 35
这会给你想要的外连接结果
select
d.name as department,
f.name as father,
sum_print as sum
from
department d
left join department f on f.id = d.father
left join
(
select
department,
sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE)
AND CAST('2020-1-15' AS DATE)
group by department
) as tmp on tmp.department = d.id
UNION
select
d.name as department,
f.name as father,
sum_print as sum
from
department d
left join department f on f.id = d.father
right join
(
select
department,
sum(page*copy) as sum_print
from print
where date between CAST('2020-1-13' AS DATE)
AND CAST('2020-1-15' AS DATE)
group by department
) as tmp on tmp.department = d.id;