Oracle Statement不正确

时间:2013-01-24 13:57:46

标签: sql oracle

我有一个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个结果。 哪里出错了?

感谢您的帮助!

2 个答案:

答案 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