我有以下疑问:
select
a.dormid, a.student_capacity, count(*) as num
from
(select
d.dormid,
d.dorm_name,
d.student_capacity,
h.amenid
from
(Dorm d left join Has_amenity h
on d.dormid=h.dormid)
) a
group by a.dormid, a.student_capacity
结果如下:
+--------+------------------+-----+
| dormid | student_capacity | num |
+--------+------------------+-----+
| 109 | 128 | 8 |
| 104 | 256 | 3 |
| 160 | 400 | 12 |
| 100 | 85 | 5 |
| 117 | 40 | 1 |
| 110 | 116 | 5 |
| 140 | 355 | 6 |
+--------+------------------+-----+
我只想得到最大值为'num'的dorm\u id和student\u capacity行(但是考虑到关系,所以我不能将行限制为1)。所以在这种情况下,返回 [160, 400, 12]
.
我该如何处理这个问题?我试着把 where num = max(num)
但那没用。我认为使用 rank
函数和限制rank=1可能会有所帮助,但我不确定应该在哪里实现它。
3条答案
按热度按时间lqfhib0f1#
诸如max、min、ave等聚合函数属于查询的select部分,而不是where。此外,不能嵌套聚合函数,因此max(count*)将不起作用。但是,您可以嵌套selects,从而以这种方式嵌套聚合函数。下面的例子来自omg ponies在这里的一篇类似文章:我可以在sql中执行max(count(*)吗
对于像你这样简单的初学者,我推荐这种方法,因为它更简单,但是madhur的答案和你使用rank work的本能也很好。
osh3o9ms2#
如果您使用的是mysql verison 8,那么您可以尝试使用with子句:
68de4m5k3#
首先也是最重要的一点,我认为您不必要地使用子选择查询(派生表)来获取当前结果。因为您没有对子查询结果进行任何进一步的过滤;您可以去掉子查询,仍然可以更有效地获得相同的结果:
现在,你基本上需要
Dense_Rank()
功能性(排名第一的宿舍设施最多)。窗口函数仅在mysql 8.0.2及更高版本中可用。在mysql<8.0.2的版本中,我们可以使用用户定义的变量来计算相同的值。这种方法的基本要点是在派生表中按所需顺序获取结果集。在这种情况下,我们关心的是排名最高的宿舍;所以我们得到结果集的降序
num
.现在,我们使用两个会话变量来存储前面的行值,以便在
Select
条款。我们基本上存储前一行rank
以及num
价值观;以及if
当前行的num
值与前一行不同,我们增加rank
.最后,再次使用这个结果作为派生表,我们只需要考虑
rank = 1
(使用Where
条款。)尝试以下查询(适用于所有mysql版本):