我有以下查询:
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_id和student_capacity行(但是允许使用联系,所以我不能仅将行限制为1)。
因此,在这种情况下,返回[160, 400, 12]
。
我该如何处理?我尝试将where num = max(num)
放在代码后面,但这没用。一世
认为使用rank
函数并限制rank = 1可能会有所帮助,但是我不确定应该在哪里实现。
答案 0 :(得分:0)
如果您使用的是MySQL版本8,则可以使用WITH子句尝试类似的操作:
WITH
counts AS (select dorm_id,count(*) as num from Dorm)
select dormid, dorm_capacity,count(*)
from Dorm
having count(*)=(select max(num) from counts)
答案 1 :(得分:0)
首先,我认为您不必要使用子选择查询(Derived Table)来获取当前结果。由于您没有对子查询结果做任何进一步的过滤;您可以取消子查询,仍然可以更有效地获得相同的结果:
SELECT
d.dormid,
d.student_capacity,
COUNT(d.dormid) AS num
FROM Dorm AS d
LEFT JOIN Has_amenity AS h
ON h.dormid = d.dormid
GROUP BY d.dormid, d.student_capacity
现在,您基本上需要Dense_Rank()
功能(等级1是拥有最大便利设施的宿舍)。 Window functions仅在MySQL versions 8.0.2 and onwards中可用。
在 MySQL <8.0.2 版本中,我们可以利用User-defined variables进行计算。这种方法的基本要点是在“派生表”中以所需顺序获取结果集。在这种情况下,我们关注排名最高的宿舍;因此我们以num
的降序获得结果集。
现在,我们利用两个会话变量在Select
子句中存储先前的行值,以便确定当前的行值。我们基本上存储了前一行的rank
和num
值;并且if
当前行的num
值与上一行不同,我们增加rank
。
最终,再次将此结果用作“派生表”,我们只需要考虑其中rank = 1
(使用Where
子句的那些行)
尝试以下查询(适用于所有MySQL版本):
SELECT dt2.*
FROM
(
SELECT
dt.dormid,
dt.student_capacity,
@drank := IF(@n <> dt.num, @drank + 1, @drank) AS rank,
@n := dt.num AS num
FROM
(
SELECT
d.dormid,
d.student_capacity,
COUNT(d.dormid) AS num
FROM Dorm AS d
LEFT JOIN Has_amenity AS h
ON h.dormid = d.dormid
GROUP BY d.dormid, d.student_capacity
ORDER BY num DESC
) AS dt
CROSS JOIN (SELECT @drank := 0,
@n := 0) AS user_init_vars
) AS dt2
WHERE dt2.rank = 1
答案 2 :(得分:0)
诸如MAX,MIN,AVE等集合函数属于查询的select部分,而不属于where。此外,您不能嵌套聚合函数,因此Max(Count *))将不起作用。但是,您可以嵌套选择,从而以这种方式嵌套聚合函数。以下示例摘自OMG Ponies的类似文章:Can I do a max(count(*)) in SQL
SELECT MAX(y.num) FROM
(SELECT COUNT(*) AS num FROM TABLE x) y
对于像您这样简单而又初级的查询,我会推荐这种方法,因为它比较简单,但是Madhur的回答和您使用Rank的直觉也很完美。