如何仅针对符合某些标准的组与其他组进行比较,对分组结果集进行过滤?例如,只有那些具有最大组成记录数的组?
我曾经认为如下的子查询可以解决这个问题:
SELECT * FROM (
SELECT *, COUNT(*) AS Records
FROM T
GROUP BY X
) t HAVING Records = MAX(Records);
然而,添加最终的HAVING
子句导致空记录集......发生了什么?
答案 0 :(得分:4)
在MySQL中(我假设您正在使用,因为您发布了SELECT *, COUNT(*) FROM T GROUP BY X
哪个会在我知道的所有RDBMS中失败)。您可以使用:
SELECT T.*
FROM T
INNER JOIN
( SELECT X, COUNT(*) AS Records
FROM T
GROUP BY X
ORDER BY Records DESC
LIMIT 1
) T2
ON T2.X = T.X
这已在MySQL中测试过,并删除了隐式分组/聚合。
如果您可以使用窗口函数和带有Ties或Common Table表达式的TOP / LIMIT之一,它会变得更短:
窗口函数+ CTE:(MS SQL-Server和PostgreSQL测试)
WITH CTE AS
( SELECT *, COUNT(*) OVER(PARTITION BY X) AS Records
FROM T
)
SELECT *
FROM CTE
WHERE Records = (SELECT MAX(Records) FROM CTE)
带TOP的窗口函数(经过MS SQL Server测试)
SELECT TOP 1 WITH TIES *
FROM ( SELECT *, COUNT(*) OVER(PARTITION BY X) [Records]
FROM T
)
ORDER BY Records DESC
最后,我从来没有使用过oracle,因为没有添加适用于oracle的解决方案......
编辑
我的MySQL解决方案没有考虑到关系,我的建议是在脚趾上解决你想要避免的这种步骤(重复子查询),所以我不确定我能帮忙吗所有,但是,以防万一这里的版本更适合你的小提琴:
SELECT T.*
FROM T
INNER JOIN
( SELECT X
FROM T
GROUP BY X
HAVING COUNT(*) =
( SELECT COUNT(*) AS Records
FROM T
GROUP BY X
ORDER BY Records DESC
LIMIT 1
)
) T2
ON T2.X = T.X
答案 1 :(得分:1)
对于您提出的确切问题,一种查看方法是,您希望记录组中没有其他组具有更多记录。所以,如果你说
SELECT taxid, COUNT(*) as howMany
GROUP by taxid
你获得所有县及其数量
然后,您可以通过将表达式作为子查询来将其表示为表,并为其指定别名。下面我将查询的两个“副本”分配给名称X和Y,并要求在一个表中没有任何更多的出租车。如果有两个具有相同的数字,我会得到两个或更多。不同的数据库具有专有语法,特别是TOP和LIMIT,使这种查询更简单,更容易理解。
SELECT taxid FROM
(select taxid, count(*) as HowMany from flats
GROUP by taxid) as X
WHERE NOT EXISTS
(
SELECT * from
(
SELECT taxid, count(*) as HowMany FROM
flats
GROUP by taxid
) AS Y
WHERE Y.howmany > X.howmany
)
答案 2 :(得分:0)
试试这个:
SELECT * FROM (
SELECT *, MAX(Records) as max_records FROM (
SELECT *, COUNT(*) AS Records
FROM T
GROUP BY X
) t
) WHERE Records = max_records
对不起,我现在无法测试此查询的有效性。