2011-05-11 58 views
0

我在回答值为0时遇到问题,当答案为空时,我的当前代码如下所示。显示0为空值的故障

select distinct bt2.isbn, bt2.btname, Count ('bcid') 

from 
booktitle bt1, booktitle bt2, 
bookcopy bc1, bookcopy bc2, 
loan l1, loan l2 

where 
bt1.isbn = bc1.isbn 
and bc1.bcid = l1.bcid 
and l1.bcid = l2.bcid 
and l2.bcid = bc2.bcid 
and bc2.isbn = bt2.isbn 


group by bt2.isbn, bt2.btname 

order by Count ('bcid') desc; 

我怎样才能得到结果的答案,显示值为0,因为他们当前没有返回行由于空值。我曾尝试使用以前回答的问题来帮助我,但似乎无法理解这个概念。任何和所有帮助将非常感激


使用至今好心所提供的所有帮助我想出了这个代码

select bt1.isbn, bt1.btname, Count (bc.bcid)  


from booktitle bt1 
    inner join bookcopy bc 
    on bc.isbn = bt1.isbn 
    inner join loan l 
    on l.bcid = bc.bcid 

    left outer join Bookcopy bc2 
    on bc2.isbn = bt1.isbn 

group by bt1.isbn, bt1.btname 
order by Count (2bc.bcid) desc; 

但是似乎仍然只返回有级数大排然后0,是否有办法让它返回count = 0的行以及count更大的行?

+1

请解释这个查询应该做什么。你可能需要一个'外部'加入。不确定你所有的6张桌子是否有必要。 – 2011-05-11 18:36:01

+0

@Philip - 这是关于查找重复行的查询吗? – rskar 2011-05-11 18:45:27

+0

@rskar - 菲利普不是OP。他们只是编辑了这个问题。 – 2011-05-11 18:49:00

回答

4

基于内部联接的查询只会在数据存在时生成行。例如,如果“bt2”中的行在“bt1”中没有匹配的连接,那么您将不会在最终集合中获得这些bt2行。

要生成一个包含所有bt2s的集合(即使没有匹配的bt1s),您也需要使用外部连接。修改代码以使用ON子句(除强制性的,如果你要与外部连接的工作),你会切换

from booktitle bt2 
inner join bookcopy bc2 
    on bc2.isbn = bt2.isbn 
inner join loan l2 
    on l2.bcid = bc2.bcid 
inner join loan l1 
    on l1.bcid = l2.bcid 
inner join bookcopy bc1 
    on bc1.bcid = l1.bcid 
inner join Booktitle bt1 
    on bt1.isbn = bc1.isbn 

from booktitle bt2 
inner join bookcopy bc2 
    on bc2.isbn = bt2.isbn 
inner join loan l2 
    on l2.bcid = bc2.bcid 
inner join loan l1 
    on l1.bcid = l2.bcid 
inner join bookcopy bc1 
    on bc1.bcid = l1.bcid 
LEFT OUTER JOIN Booktitle bt1 
    on bt1.isbn = bc1.isbn 

这将产生具有行所有bt2数据(假设所有这些介入内部连接都已经完成),而在bt1结果集中没有数据(由NULL表示)。更糟的是关闭的从BT1集中的列计数,你应该把你的零:

SELECT distinct bt2.isbn, bt2.btname, Count (bt1.isbn)  
from booktitle bt2 
    inner join bookcopy bc2 
    on bc2.isbn = bt2.isbn 
    inner join loan l2 
    on l2.bcid = bc2.bcid 
    inner join loan l1 
    on l1.bcid = l2.bcid 
    inner join bookcopy bc1 
    on bc1.bcid = l1.bcid 
    left outer join Booktitle bt1 
    on bt1.isbn = bc1.isbn 
group by bt2.isbn, bt2.btname 
order by Count (bt1.isbn) desc 
+0

感谢您的回复,以及您逐步完成工作的方式,这对我来说非常有帮助,但是代码仍然给出了与我的初始代码相同的结果(仍然缺少count = 0的行) – Tom 2011-05-12 14:33:27

+0

计数是为bcid而不是isbn(位于bookcopy表格中,而不是书名)抱歉,如果我确定清楚 – Tom 2011-05-12 14:46:51

+0

我去了一个更简单的描述。如果在任何其他表中存在“bt2”表中的值,即使* nothing * else“匹配”,那么您应该将它们全部设置为“左外部连接”。 – 2011-05-12 15:55:10

1

重构原始查询使用正确的联接语法给了我这样的:

select bt2.isbn , 
     bt2.btname , 
     Count ('bcid') 
from booktitle bt1 , 
join bookcopy bc1 on bc1.isbn = bc1.isbn 
join loan  l1 on l1.bcid = bc1.bcid 
join loan  l2 on l2.bcid = l1.bcid 
join bookcopy bc2 on bc2.bcid = l2.bcid 
join booktitle bt2 on bt2.bcid = bc2.bcid 
group by bt2.isbn, bt2.btname 
order by Count ('bcid') desc 

仍然没有按并不清楚你想要完成什么。但是,如果我们延长您的查询中使用左全线加入,从而

select * 
from  booktitle bt1 
left join bookcopy bc1 on bc1.isbn = bc1.isbn 
left join loan  l1 on l1.bcid = bc1.bcid 
left join loan  l2 on l2.bcid = l1.bcid 
left join bookcopy bc2 on bc2.bcid = l2.bcid 
left join booktitle bt2 on bt2.bcid = bc2.bcid 

你会得到至少1排在booktitle每个条目:任何连接不匹配将其所有列设置(如果您的SQL引擎符合标准,则会向下传播),则null将通过is [not] null失败,所有测试都将保存显式测试的无效性。这给了我们我们的候选集,我们需要总结。匹配整个连接链的行将具有非空列bt2;那些列将包含所有不匹配整个连接链的行的所有null值。

您想要计算bt1中有多少个条目与整个连接链相匹配,由isbn/btname分开。为此,我们添加我们需要的分组列和我们需要的聚合函数。下面的意志,我相信,这样的伎俩,根据我的理解(如它是)原始查询:

select bt1.isbn , 
     bt1.btname , 
     sum(case when bt2.bcid is not null then 1 else 0 end) 
from  booktitle bt1 
left join bookcopy bc1 on bc1.isbn = bc1.isbn 
left join loan  l1 on l1.bcid = bc1.bcid 
left join loan  l2 on l2.bcid = l1.bcid 
left join bookcopy bc2 on bc2.bcid = l2.bcid 
left join booktitle bt2 on bt2.bcid = bc2.bcid 
group by bt1.isbn, bt1.btname 
order by 3 desc , 
     1 , 
     2 

你会注意到sum(case...end),其中case表达作为一个判别函数产生可以计数的0/1值;通过简单的count(tb2.bcid)可以实现相同的结果,因为空值不会被集合函数考虑,唯一的例外是count(*)。我更喜欢使用sum(case ... end)技术,因为它明确地表达了意图:任何对SQL不了解的人都会发现结果不那么令人惊讶。

希望这会有所帮助。

+0

我非常感谢您的努力帮助我,这段代码给了我一些疯狂的结果,我只是了解所有的大声笑(我对sql很陌生),但我感谢你的时间和精力, – Tom 2011-05-12 14:45:13