SQL获取按计数排名的项目(*)

时间:2018-02-06 05:46:06

标签: sql oracle

我一直在尝试以下查询 - 不知道如何解决我遇到的这个问题。

我需要获得覆盖第二大音乐风格的乐队 - 包括所有相同的乐队如果有第二个并列。例如表band_style,

Band_id    |  Style
---------------------
1            Rock
2            Pop
1            Punk
3            Classical
1            Metal
2            Rock
4            Pop
4            Rap

返回的结果应为

Band_id   | Num_styles
  2          2
  4          2

我最初尝试解决方案:

SELECT band_id, COUNT(*) AS num_styles FROM band_style 
GROUP BY band_id HAVING COUNT(*) <
(SELECT MAX(c) FROM
(SELECT COUNT(band_id) AS c
FROM band_style
GROUP BY band_id));

所以这给了我所有乐队的数量,它们的风格少于最大乐队。现在,我想要获取具有此查询的最大值的所有行。我不想使用rownum或限制,因为根据我的经验,这在关系的情况下不能很好地工作。我也想知道是否有办法将其包装在另一个MAX函数中,但我真的不知道如何。

对此问题的任何帮助都将不胜感激 - 也认为这有助于了解它是否可以应用于第3,第4高等等。

(使用Oracle / SQLPlus) 假设这是一个大型数据文件,我们不一定知道“第二高的数量”是什么。

更新:这几乎可以工作 - 所有乐队都会获得少于最大数量的乐队。但是调用MAX似乎不起作用,因为返回的表仍然具有NUM的所有值,除了max ..

WITH data AS (
SELECT band_id, COUNT(*) AS NUM FROM band_style GROUP BY band_id HAVING COUNT  (*) < 
(SELECT MAX(c) FROM
(SELECT COUNT(band_id) AS c
FROM band_style
GROUP BY band_id)))
SELECT data.band_id, data.NUM FROM data
INNER JOIN ( SELECT band_id m, MAX(NUM) n 
         FROM data GROUP BY band_id
       ) t
   ON t.band_id = data.band_id 
     AND t.NUM = data.NUM;

1 个答案:

答案 0 :(得分:0)

如果你必须坚持使用mysql,这个sql将会困难得多。但如果您可以切换到 mariadb oracle ,这应该可行。

     public class BitTypeCharConvention : Convention
        {
            private const string DataType = "BITTYPE:char(1)";

            public BitTypeCharConvention()
            {
                Properties<bool>().Configure(c => c.HasColumnType(DataType));
            }
        }

http://sqlfiddle.com/#!4/dc3f6/12

这里的朋友是窗口功能 dense_rank

输出结果为:

with data as (
  select 
  band_id, count(*) styles, 
  dense_rank() over (order by count(*) desc) place 
  from 
  table1 group by band_id)
select * from data where place=2

这里为了避免一些误解,因为地方2就是风格2。

http://sqlfiddle.com/#!4/2be32/3

现在样式数与地点ID不同。

BAND_ID  STYLES  PLACE
2        2       2
4        2       2

这表明dense_rank事先并不知道第二高的计数值。