当答案为空时,我在结果中返回值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的行以及计数更大的行?
答案 0 :(得分:4)
基于内部联接的查询只会在数据存在时生成行。例如,如果“bt2”中的行在“bt1”中没有匹配的连接,那么您将不会在最终集合中获得这些bt2行。
即使没有匹配的bt1,要生成一个包含(比如说)所有bt2的集合,你需要使用外连接。修改你的代码以使用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
答案 1 :(得分: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
对于booktitle
中的每个条目,您将获得至少一行:任何不匹配的连接都将其所有列设置为null,这将沿着连接链向下传播(如果您的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的理解不符合鼻烟的人都会发现结果更少......令人惊讶。
希望这有帮助。