相互比较SQL组

相互比较SQL组,sql,group-by,Sql,Group By,与其他组相比,如何仅为满足某些条件的组筛选分组结果集?例如,只有那些拥有最多组成记录的组 我原以为下面的子查询应该可以做到这一点: SELECT * FROM ( SELECT *, COUNT(*) AS Records FROM T GROUP BY X ) t HAVING Records = MAX(Records); 但是,添加finalHAVING子句会导致一个空记录集。。。发生了什么事?试试这个: SELECT * FROM ( SELEC

与其他组相比,如何仅为满足某些条件的组筛选分组结果集?例如,只有那些拥有最多组成记录的组

我原以为下面的子查询应该可以做到这一点:

SELECT * FROM (
    SELECT   *, COUNT(*) AS Records
    FROM     T
    GROUP BY X
) t HAVING Records = MAX(Records);
但是,添加final
HAVING
子句会导致一个空记录集。。。发生了什么事?

试试这个:

SELECT * FROM (
  SELECT *, MAX(Records) as max_records FROM (
    SELECT *, COUNT(*) AS Records
    FROM T
    GROUP BY X
  ) t
) WHERE Records = max_records

很抱歉,我现在无法测试此查询的有效性。

对于您给出的确切问题,一种查看方法是,您希望记录组中没有其他组具有更多记录。所以如果你说

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
)
在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中进行了测试,并删除了隐式分组/聚合

如果可以使用带窗口的函数和一个TOP/LIMIT with Ties或通用表格表达式,它会变得更短:

窗口函数+CTE:(已测试MS SQL Server和PostgreSQL)

带顶部的窗口功能(经MS SQL Server测试)

最后,我从未使用过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

如果Juho的回答不能满足您的需要,请输入您正在使用的数据库类型(oracle、mysql、sql server等)(使用标签,将其放入sql中。如果您只需要通用sql解决方案,请在邮件正文中提及)。如果您有时间在帖子和sqlfiddle.com上发布一些示例数据和表结构,您将使人们更容易深入地了解您的问题。@LevinMagruder:MySQL 5.1;好的,我不使用mysql,但是有人会向你展示一个比我下面展示的更简单的查询,将他们的答案标记为答案,但是如果我的答案有用,你想向我投赞成票,谢谢。如果你有很多这样的问题,也可以阅读题为“每个小组最多n个”的问题,这里有很多有趣的方法。@LevinMagruder:谢谢Levin;我会投票支持你的答案,因为它确实有帮助(并且是处理问题的一种策略),但我会坚持等待一个可以避免重复子查询的答案(如果可能的话!)。
SELECT MAX(Records)
在第二级查询中,将记录集截断为仅一条记录,其中
记录
最大记录
字段不一定相同(因此总体结果将仅由零条或一条记录组成);也许这就是我的原始查询所暗示的,因此没有结果?我知道,通过在
WHERE
子句中重复子查询,我能够提取最大行数(只需使用
max()
there就可以了),但多次调用同一子查询似乎相当浪费;有没有办法引用
WHERE
子句中
from
子句中的子查询产生的临时表?但是第一个(mysql)表没有关联;这可能是eggyal想要的,如果不是的话,我认为你必须重铸它以匹配计数。最后两个不会失去联系。@LevinMagruder是的,几分钟前注意到了这一点,添加了一个编辑,但现在我也不认为这是OP想要的,因为它重复子查询,但据我所知,这是不可避免的。
SELECT  TOP 1 WITH TIES *
FROM    (   SELECT  *, COUNT(*) OVER(PARTITION BY X) [Records]
            FROM    T
        )
ORDER BY Records DESC
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