2013-01-24 29 views
2

我得到一个SQL语句 - 对我来说不能解释 - 奇怪的行为。 也许你会发现什么是错的:Oracle声明不能正确计数

当我使用

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结果。 错误在哪里?

感谢您的帮助!

+1

该死的,我的第3次后大脑失去了联系加盟。什么是“不计数”选择内部选择给你(行计数说)...并且是建筑物唯一? – Najzero

+0

嗨Najzero,是的,我知道,这个说法有点复杂。如果我计算内部选择,我得到了2755结果(与工会所有)。 buildingid在构建表中是唯一的 – Tom

+0

Buildingid不是您正在组合的两个查询中行的唯一标识,因此您将获得@LievenKeersmaekers描述的复制效果 – GTG

回答

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语句

select * from TableA a left outer join TableB b on a.name = b.name 

由于TableA每个记录与匹配的TableB每个记录,其中name是平等的,这将导致4条(该AnyOtherValue被dissmissed因为它不匹配)

  • TableA的第一条记录与二三记录`表B返回的“
  • TableA第二个记录与二三记录`表B返回的”
+0

因此,当我在TableA中具有2755条记录和2755条记录时在TableB中,我应该得到7590025个结果......但是我得到了3648513个结果,这比结果的一半还要少。 – Tom

+0

@汤姆 - 我明白你的意思,但你不能只是乘以,这一切都取决于有多少记录匹配。我已经改变了我的例子,告诉你它不只是2 * 3 *(或2755 * 2755)*。 –

+0

@Tom - 如果它是一个交叉连接,这将是真实的,形成两个表的笛卡尔积;但你还在加入'buildid',这会减少比赛次数。 –

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(注意与其他值的记录不会被包括,这可能会或可能不会成为一个问题取决于此列的限制)。

此查询结果的唯一键可能类似于departmentid(您需要在选择标准中包含该列)。

所以正确的查询应该是这个样子:

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名称

11 DEPT1

2 2部门2

3 2 Dept3

的倍增效应并不完全等于deptcount * deptcount,而是它是buildingcount * buildingcount + deptcount - buildingcount

+0

我试图使用该ID,但我得到了“缺少的关键字” - 错误,但我不会放弃;-) – Tom

+0

查看更新后的查询... – GTG