【问题标题】:How to select the highest value after a count() | Sql Oracle如何在 count() 之后选择最大值 |甲骨文
【发布时间】:2016-10-20 19:13:01
【问题描述】:

这是我的查询:

SELECT f.name, COUNT(*) as num_books
from author f
JOIN book b on b.tittle = f.book
Group by f.name

这给了我这张桌子:

NAME                                                NUM_BOOKS
-------------------------------------------------- ----------
Dyremann                                                    2
Nam mann                                                    1
Thomas                                                      1
Asgeir                                                      1
Tullemann                                                   5
Plantemann                                                  1
Beste forfatter                                             1
Fagmann                                                     5
Lars                                                        1
Hans                                                        1
Svein Arne                                                  1

如何轻松更改查询以仅显示已发行图书数量最多的作者? (但请记住,我对 sql 比较陌生)

【问题讨论】:

  • 数据库版本? select * from v$version;
  • 如果你有多个顶级作者,你想怎么做?
  • Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production ,这可能是你的 oracle 12c 不能工作的原因
  • 我不介意展示所有顶级作者
  • 我在答案中添加了额外的选项

标签: sql oracle count max


【解决方案1】:

Oracle,据我所知,只有 Oracle 允许您嵌套两个聚合函数。

SELECT max (f.name) keep (dense_rank last order by count (*)) as name
from author f
JOIN book b on b.tittle = f.book
Group by f.name

为了获得所有顶级作者:

select   name
from    (SELECT f.name,rank () over (order by count(*) desc) as rnk
         from author f
         JOIN book b on b.tittle = f.book
         Group by f.name
         ) 
 where   rnk = 1

从 Oracle 12c 开始:

SELECT f.name
from author f
JOIN book b on b.tittle = f.book
Group by f.name
order by count (*) desc
fetch first row /* with ties (optional, in order to get all top authors) */

【讨论】:

  • 谢谢你,就像一个魅力。但是,我将如何更改显示屏上方的文本?我之前用 AS 更改过,现在我找不到适合 AS 的地方。
  • 不客气。 AS 总是出现在表达式的末尾。我已经相应地编辑了我的答案。
  • 那一定是我名字里的随机空格或类似的东西。我第一次尝试时它没有用。不过谢谢!
  • 如果你想使用带空格或特殊字符的别名,你可以用双引号括起来,例如as "this is a special alias!"
  • “获取第一行”解决方案(Oracle 12)将错过顶部的联系(我认为)。
【解决方案2】:

最好的办法是使用:

SELECT f.name, COUNT(*) as num_books
from author f
JOIN book b on b.tittle = f.book
Group by f.name
Order by num_books DESC
FETCH FIRST ROW ONLY

这会将结果从大到小排序并返回第一个结果。

【讨论】:

  • 这仅适用于 Oracle 12 及更高版本 - 它会错过“大多数书籍”的联系。
【解决方案3】:

1)Oracle 特定:(使用 ROWNUM,对于 Postgres/MySql 使用限制)

select * from 
(SELECT f.name, COUNT(*) as num_books
from author f
JOIN book b on b.tittle = f.book
Group by f.name order by num_books desc )
 where ROWNUM = 1

2) 所有数据库的通用查询:

select f.name,count(*) as max_num_books from author f
JOIN book b on b.tittle = f.book
Group by f.name
having count(*) = 
(select max(num_books) 
from 
(SELECT f.name, COUNT(*) as num_books
from author f
JOIN book b on b.tittle = f.book
Group by f.name)
);

【讨论】:

    【解决方案4】:

    我不知道你为什么首先需要加入。看来author 表有一个列book - 为什么从该表中count(book)name 分组还不够?这种安排很奇怪——author 表应该只有作者属性,作者姓名应该在title 表中,但你确实加入了author.book = book.title,这似乎暗示你这样做,事实上,有奇怪的安排(因此您不需要加入)。此外,最好避免让一个表和一个列(在另一个表中)共享相同的名称 book

    在这种情况下,最基本的解决方案(虽然不是最有效的)是

    select name, count(book) as max_num_books
    from   author
    group by name
    having count(book) = (select max(count(book) from author group by name);
    

    子查询按名称分组,然后选择所有组计数中的最大值。外部查询选择书籍计数等于此最大值的名称。子查询在单个列中返回单个行 - 单个值。这样的查询称为“标量”子查询,可以在需要单个值的任何地方使用,例如外部查询的 HAVING 子句。 (它在 HAVING 子句中而不是 WHERE 子句中,因为它引用组属性 - count(book) - 而不是单个行属性)。

    如嘟嘟所示,更有效的解决方案是:

    select name, ct as max_num_books
    from   ( select name, count(*) as ct, rank() over (order by count(*) desc) rnk
             from   author
             group by name
           )
    where rnk = 1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 2021-11-24
      • 1970-01-01
      • 2020-06-09
      • 2020-03-02
      • 1970-01-01
      • 2016-12-21
      相关资源
      最近更新 更多