我有一个SQL语句,对我来说不可解释 - 奇怪的行为。 也许你可以找到错误的地方:
当我使用语句
时select count(*) from department
我得到了2755个结果
使用以下声明
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
我也得到了2755个结果。 但是,当我想将两个语句与左连接组合时:
select count(*) from department
left join
(
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
) postadress
on
department.buildingid = postadress.buildingid;
我得到了3648513个结果。
我的期望是,我只获得了2755个结果。 哪里出错了?
感谢您的帮助!
答案 0 :(得分:3)
我认为buildingid
不是唯一(因为我的理由是保持为真,它不能是唯一的)
想象一下下面的简单表格
<强>表A 强>
create TableA (name VARCHAR(32));
insert into TableA values ('Lieven');
insert into TableA values ('Lieven');
<强>表B 强>
create TableB (name VARCHAR(32));
insert into TableB values ('Lieven');
insert into TableB values ('Lieven');
insert into TableB values ('AnyOtherValue');
选择语句
select * from TableA a left outer join TableB b on a.name = b.name
由于 TableA
的每个记录与TableB
相等的name
的每个记录匹配,这将导致4条记录(AnyOtherValue因不匹配而被解雇)
TableA
的第一条记录,其中包含三条“TableB”记录中的两条TableA
的第二条记录,其中包含三条“TableB”记录中的两条答案 1 :(得分:1)
查询
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
将每个使用usepostaladresssupporter的部门返回一行作为0或1(请注意,不包含具有其他值的记录,这可能是也可能不是问题,具体取决于此列的约束)。
此查询结果的唯一键可能类似于离开(您需要在选择条件中包含该列)。
所以正确的查询应该是这样的:
select * from department
left join
(
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.departmentid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.departmentid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
) postadress
on
department.departmentid = postadress.departmentid;
您的查询在这样的数据上会出错:
Departmentid BuildingId Name
1 1 Dept1
2 2 Dept2
3 2 Dept3
乘法效果不等于deptcount * deptcount,而是建筑数量* buildingcount + deptcount - buildingcount