比较SQL组彼此

时间:2012-03-27 13:27:37

标签: sql group-by

如何仅针对符合某些标准的组与其他组进行比较,对分组结果集进行过滤?例如,只有那些具有最大组成记录数的组?

我曾经认为如下的子查询可以解决这个问题:

SELECT * FROM (
    SELECT   *, COUNT(*) AS Records
    FROM     T
    GROUP BY X
) t HAVING Records = MAX(Records);

然而,添加最终的HAVING子句导致空记录集......发生了什么?

3 个答案:

答案 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

对不起,我现在无法测试此查询的有效性。