【发布时间】:2016-04-20 05:37:25
【问题描述】:
我需要分别计算邮政编码为 44444 的付款人和凡人。他们的邮政编码存储在同一个表中,但他们的 ID 在多对多关系中的两个单独的表中。我写了这个:
select count(mortal_zip) as "Mortals in 44444"
,count(payer_zip) as "Payers in 44444"
from
(select am.zip_code as mortal_zip
from address am
join mortal_address
on mortal_address.address_id = am.address_id
join mortal
on mortal.mortal_id = mortal_address.mortal_id
where trim(am.zip_code) = '44444'
) m,
(select ap.zip_code as payer_zip
from address ap
join payer_address
on payer_address.address_id = ap.address_id
join payer
on payer.payer_id = payer_address.payer_id
where trim(ap.zip_code) = '44444'
) p;
我知道:没有邮政编码为 44444 的付款人,但有 3 个邮政编码为 44444 的凡人。出于某种原因,我知道有 0 个邮政编码为 44444 的凡人。如果我问对于 44444 中的凡人,我得到了我需要的东西。如果我用 444444 询问凡人的数量和付款人的数量,我得到的两边都是 0。
此外,我尝试使用子选择重新编写整个内容。
select count(m.mortal_zip) as "Mortals in 44444"
,count(p.payer_zip) as "Payers in 44444"
from
(select am.zip_code as mortal_zip
from address am
where trim(am.zip_code) = '44444'
and am.address_id in
(select mortal_address.address_id
from mortal_address
where mortal_address.mortal_id in
(select mortal.mortal_id
from mortal
)
)
) m,
(select ap.zip_code as payer_zip
from address ap
where trim(ap.zip_code) = '44444'
and ap.address_id in
(select payer_address.address_id
from payer_address
where payer_address.payer_id in
(select payer.payer_id
from payer
)
)
) p;
我得到相同的结果。
为什么另一个 select 语句中的 where 函数会影响另一个 select 语句?
更新
我已经重新编写了查询,但这两个查询返回的值不同。
这个:
select m.mortal_zip as "Mortals in 44444"
,p.payer_zip as "Payers in 44444"
from
(select count(am.zip_code) as mortal_zip
from address am
where trim(am.zip_code) = '44444'
and am.address_id in
(select mortal_address.address_id
from mortal_address
where mortal_address.mortal_id in
(select mortal.mortal_id
from mortal
)
)
) m,
(select count(ap.zip_code) as payer_zip
from address ap
where trim(ap.zip_code) = '44444'
and ap.address_id in
(select payer_address.address_id
from payer_address
where payer_address.payer_id in
(select payer.payer_id
from payer
)
)
) p;
返回:
Mortals in 44444 Payers in 44444
---------------- ---------------
3 0
这个:
select mortal_zip as "Mortals in 44444"
,payer_zip as "Payers in 44444"
from
(select count(am.zip_code) as mortal_zip
from address am
join mortal_address
on mortal_address.address_id = am.address_id
join mortal
on mortal.mortal_id = mortal_address.mortal_id
where trim(am.zip_code) = '44444'
) m,
(select count(ap.zip_code) as payer_zip
from address ap
join payer_address
on payer_address.address_id = ap.address_id
join payer
on payer.payer_id = payer_address.payer_id
where trim(ap.zip_code) = '44444'
) p;
返回:
Mortals in 44444 Payers in 44444
---------------- ---------------
5 0
【问题讨论】:
-
请尽量避免您在那里进行的连接类型。阅读笛卡尔连接。您实际上是在进行 CROSS JOIN,但由于查询的一侧是空的,因此您没有得到任何结果。您要做的是使用基表,然后对您所做的每个子选择执行 LEFT JOIN。这将允许在不抑制数据的情况下返回 NULL 值。
-
为什么需要修剪邮政编码?您是否知道或怀疑它周围可能有不必要的空间?如果是这样,使用类似这样的东西会更有效: where am.zip_code like '%44444%' - 尽可能避免在函数中包装列值。
-
@mathguy 邮政编码字段是 varchar 数据类型,包含 15 个字符空格。