我可以在 SQL 中执行 max(count(*)) 吗?
这是我的代码:
select yr,count(*)
from movie
join casting on casting.movieid=movie.id
join actor on casting.actorid = actor.id
where actor.name = 'John Travolta'
group by yr;
这是问题:
那是“约翰·特拉沃尔塔”最忙碌的几年。显示他每年制作的电影数量。
这是表结构:
movie(id, title, yr, score, votes, director)
actor(id, name)
casting(movieid, actorid, ord)
这是我得到的输出:
yr count(*)
1976 1
1977 1
1978 1
1981 1
1994 1
-- etc.
我需要获取 count(*)
为 max 的行。 我该怎么做?
Here's my code:
select yr,count(*)
from movie
join casting on casting.movieid=movie.id
join actor on casting.actorid = actor.id
where actor.name = 'John Travolta'
group by yr;
Here's the question:
Which were the busiest years for 'John Travolta'. Show the number of movies he made for each year.
Here's the table structure:
movie(id, title, yr, score, votes, director)
actor(id, name)
casting(movieid, actorid, ord)
This is the output I am getting:
yr count(*)
1976 1
1977 1
1978 1
1981 1
1994 1
-- etc.
I need to get the rows for which count(*)
is max.
How do I do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
使用:
按
num_movies DESC
排序会将最高值放在结果集的顶部。如果许多年的计数相同,m.yr
会将最近的一年放在顶部...直到下一个num_movies
值发生变化。我可以使用 MAX(COUNT(*)) 吗?
不可以,您不能在同一 SELECT 子句中将聚合函数分层。内部聚合必须在子查询中执行。 IE:
Use:
Ordering by
num_movies DESC
will put the highest values at the top of the resultset. If numerous years have the same count, them.yr
will place the most recent year at the top... until the nextnum_movies
value changes.Can I use a MAX(COUNT(*)) ?
No, you can not layer aggregate functions on top of one another in the same SELECT clause. The inner aggregate would have to be performed in a subquery. IE:
只需按
count(*) desc
排序,您就会得到最高的(如果您将其与limit 1
结合使用)Just order by
count(*) desc
and you'll get the highest (if you combine it withlimit 1
)这个问题很旧,但在 dba.SE 上的一个新问题中引用了。我觉得还没有提供最好的解决方案。另外,还有新的、更快的选项。
标题中的问题
是,您可以通过在 窗口函数:
db<>fiddle 此处
这是标准 SQL。 Postgres 在 8.4 版本(2009-07-01 发布,在这个问题提出之前)引入了它。其他 RDBMS 应该也有同样的能力。
考虑
SELECT
查询中的事件顺序:可能的缺点:窗口函数不会聚合行。您将获得聚合步骤后剩余的所有行。在某些查询中很有用,但对于这个查询来说并不理想。
要获取计数最高的一行,您可以使用
ORDER BY ct DESC FETCH FIRST 1 ROW ONLY
:仅使用基本的 SQL 功能,可用在任何中等程度的 RDBMS 中。大多数流行的 RDBMS 也支持使用
LIMIT
、TOP
或ROWNUM
的FETCH FIRST
替代语法。请参阅:或者您可以使用
DISTINCT ON
获得最高计数的每组一行(仅 Postgres ):实际问题
计数最高的行可能不止一行。
SQL Server 拥有
WITH TIES
功能已经有一段时间了 - 使用非标准语法:db<>fiddle 此处
PostgreSQL 13 添加了
WITH TIES
使用标准 SQL 语法:db<>fiddle 此处
这应该是最快的查询。进一步阅读:
获取顶行价值最高,有联系
PostgreSQL与 TOP n WITH TIES 等效:LIMIT“with ties”?
要按附加条件对结果进行排序(或者对于旧版本的 Postgres 或其他没有
WITH TIES
的 RDBMS),请使用窗口函数rank()
在子查询中:现在所有主要的 RDBMS 都支持窗口函数。
This question is old, but was referenced in a new question on dba.SE. I feel the best solutions haven't been provided. Plus, there are new, faster options.
Question in the title
Yes, you can achieve that by nesting an aggregate function in a window function:
db<>fiddle here
That's standard SQL. Postgres introduced it with version 8.4 (released 2009-07-01, before this question was asked. Other RDBMS should be capable of the same.
Consider the sequence of events in a
SELECT
query:Possible downside: window functions do not aggregate rows. You get all rows left after the aggregate step. Useful in some queries, but not ideal for this one.
To get one row with the highest count, you can use
ORDER BY ct DESC FETCH FIRST 1 ROW ONLY
:Using only basic SQL features, available in any halfway decent RDBMS. Most popular RDBMS (also) support alternative syntax for
FETCH FIRST
withLIMIT
,TOP
orROWNUM
. See:Or you can get one row per group with the highest count with
DISTINCT ON
(only Postgres):Actual Question
There may be more than one row with the highest count.
SQL Server has had the feature
WITH TIES
for some time - with non-standard syntax:db<>fiddle here
PostgreSQL 13 added
WITH TIES
with standard SQL syntax:db<>fiddle here
This should be the fastest possible query. Further reading:
Get top row(s) with highest value, with ties
PostgreSQL equivalent for TOP n WITH TIES: LIMIT "with ties"?
To sort results by additional criteria (or for older versions of Postgres or other RDBMS without
WITH TIES
), use the window functionrank()
in a subquery:All major RDBMS support window functions nowadays.
它来自这个网站 - http://sqlzoo.net/3.htm
2 种可能的解决方案:
使用 TOP 1 ORDER BY ... DESC:
使用 MAX:
it's from this site - http://sqlzoo.net/3.htm
2 possible solutions:
with TOP 1 a ORDER BY ... DESC:
with MAX:
使用带有限制的 max 只会给出第一行,但如果有两行或更多行具有相同的最大电影数,那么您将丢失一些数据。如果您有可用的 rank() 函数,下面是一种执行此操作的方法。
Using max with a limit will only give you the first row, but if there are two or more rows with the same number of maximum movies, then you are going to miss some data. Below is a way to do it if you have the rank() function available.
下面的代码给你答案。它本质上是通过使用 ALL 来实现 MAX(COUNT(*)) 的。它的优点是它使用非常基本的命令和操作。
The following code gives you the answer. It essentially implements MAX(COUNT(*)) by using ALL. It has the advantage that it uses very basic commands and operations.
取决于您使用的数据库...
我的大部分经验都是在 Sybase 中,它使用一些与其他数据库不同的语法。但在本例中,您要命名计数列,以便可以对其进行降序排序。您可以更进一步,将结果限制为前 10 行(以找到他最繁忙的 10 年)。
Depending on which database you're using...
Most of my experience is in Sybase, which uses some different syntax than other DBs. But in this case, you're naming your count column, so you can sort it, descending order. You can go a step further, and restrict your results to the first 10 rows (to find his 10 busiest years).
-----已创建视图-----
年
2013年
-----VIEW CREATED-----
YR
2013
感谢最后一个答案
,我遇到了同样的问题:我只需要知道其计数与最大计数匹配的记录(可能是一个或多个记录)。
我必须了解有关“ALL 子句”的更多信息,这正是我正在寻找的那种简单的解决方案。
Thanks to the last answer
I had the same problem: I needed to know just the records which their count match the maximus count (it could be one or several records).
I have to learn more about "ALL clause", and this is exactly the kind of simple solution that I was looking for.
您可以将
top
与with ties
一起使用,其中包含具有最大count(*)
值的所有年份,如下所示:如果最大值为 6,您将获得计数值为 6 的所有年份。
you can use the
top
along withwith ties
, which will include all of the years having the maximumcount(*)
value, something like this:If the maximum is say 6, you'll get all of the years for which the count value is 6.