微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL – Query – max(count())

我正在为我的数据库系统考试(明天)学习,我在练习中遇到麻烦,我被要求编写查询.以下是一个例子:

我被要求写一个查询来回答以下问题:在最低年龄的作者中,谁写大部分书籍?

问题是我的老师禁止我使用FROM子句中的子查询,并使用TOP.

我已经写了一个答案,但我知道的是不正确的:

SELECT W.AName,COUNT(W.ID_B) AS NBooks
FROM Write W,Author A1
WHERE (A1.AName = W.AName) AND
      (A1.AAge = (SELECT MIN(A2.Age)
                  FROM Author A2))
GROUP BY W.AName
ORDER BY NBooks DESC

一个给所有作者年龄较低,并且写了相应的书数(我希望..).正确的答案应该只是这个的第一行.

让我清楚一点:

Table Author
AName    | AAge
---------------
John     | 25
Rick     | 30
Sean     | 26
Lena     | 25

Table Writes
AName    | ID_B
---------------
John     | 2
Lena     | 1
John     | 3
Lena     | 4
Rick     | 5
Rick     | 6
Lena     | 6
Rick     | 7
Rick     | 8

(注意,肖恩没有写任何书,书中有2位作者,而里克是大多数书籍的作者(4))

现在,我上面写的代码给出了这个结果(我猜)

AName    | NBooks
-----------------
Lena     | 3
John     | 2

(最低年龄25岁,莱娜和约翰都25岁)

问的是:

AName    | NBooks
-----------------
Lena     | 3

(Lena是作者,在所有年龄最小的作者中(25),大多数书籍都是书面的)

提前致谢

解决方法

因为你是一个学生,我会回答问题的一部分.这是一个答案,忽略最小的部分:
select a.AName,COUNT(*) as NumBooks
from Author a join
     Write w
     on a.AName = w.AName
group by a.AName
having count(*) >= all(select COUNT(*) as NumBooks
                       from write w
                       group by w.AName
                      )

我想你可以弄清楚如何修改它.

顺便说一句,限制和限制是我希望只有这个例子.否则,你应该得到另一位老师,因为这些都是非常重要的结构.

另外,您需要学习常规的连接语法,而不是在from子句中.再一次,如果你老师不教授现代sytnax(自1988年左右),得到一个新老师.而且,我认为子查询的限制也适用于CTE.

我也想指出查询的“正确”版本:

select top 1 a.aname,count(*) as NumBooks
from Author a join
     Write w
     on a.AName = w.AName
group by author.name,author.Aage
order by author.Age asc,count(*) desc

这个查询比几乎任何维度上面的查询都好.它一个连接,一组和一个.我的查询的完整版本明确地进行了两个连接,两个连接隐含(age子句)和两个组旁边.前者将比后者有更好的表现.

从可读性的角度来看,此版本更短,更干净.我也认为,教导这是做什么,而不是第一个版本中的“不寻常的”结构要容易得多.大多数学生将会了解什么顶级和顺序正在做,并可以效仿这一点.模拟发生在那个条款中需要一些精神体操.

如果要让所有作者获得最大数量,首先要意识到以前的查询相当于:

select aname,NumBooks
from (select a.aname,count(*) as NumBooks,row_number() over (partition by author.Name order by a.aAge,count(*) desc) as seqnum
      from Author a join
           Write w
           on a.AName = w.AName
      group by author.name,author.Aage
     ) aw
where seqnum = 1

切换到所有的作者是容易的:

select aname,dense_rank() over (partition by author.Name order by a.aAge,author.Aage
     ) aw
where seqnum = 1

这也比回答问题的查询效率更高.无法在from子句中使用top或subqueries就像运行一个三足的比赛.是的,你可以到达那里,但是你可以在自己的两条腿上跑得更快.

原文地址:https://www.jb51.cc/mssql/82687.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐