T-SQL 查询获取子元素的最大值

Posted

技术标签:

【中文标题】T-SQL 查询获取子元素的最大值【英文标题】:T-SQL query getting the max of a sub element 【发布时间】:2021-12-24 06:07:03 【问题描述】:

考虑这样的表格:

Category Subcategory Item
Foo Apple i1
Foo Apple i2
Foo Apple i3
Foo Pear i4
Foo Pear i5
Bar Blackberry i6
Bar Blueberry i7
Bar Blueberry i8

对于每个category,我想获得subcategory 的最高计数items。我不在乎物品的身份(甚至它们的数量)。所以,我希望最终的回报是

Category Subcategory
Foo Apple
Bar Blueberry

我试过了

WITH pool AS (
    SELECT
        category,
        subcategory,
        COUNT(item) AS "itemCount"
    FROM table
    GROUP BY category, subcategory
),
maxItems AS (
    SELECT
        category,
        MAX(subcategory), -- In real life, this is a numeric column
    FROM pool
    GROUP BY category
    HAVING itemCount = MAX(itemCount)
)
-- and final query here filtered on the category -> subcategory mapping from above

但是 HAVING 语句错误

is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.

当然当然它不在group by中。我不想按最大计数分组,我想按它过滤

我可以使它与 maxItems 中的子查询一起工作,将其更改为

maxItems AS (
    SELECT
        category,
        MAX(subcategory), -- In real life, this is a numeric column
    FROM pool
    JOIN (
        SELECT
            subcategory,
            MAX(itemCount) AS "itemCount"
        FROM pool
        GROUP BY subcategory
    ) AS "maxFilter"
        ON rmCounts.subcategory = maxFilter.subcategory
        AND maxFilter.itemCount = rmCounts.itemCount
    GROUP BY category
)

但我真的觉得如果HAVING 起作用会更优雅、更清晰,我不明白为什么它不起作用

【问题讨论】:

这能回答你的问题吗? Get top 1 row of each group @AaronBertrand 我已经接受了答案,但我并不特别在意平局,随机选择就可以了。 @Charlieface,你知道,我知道该怎么做,而且我没有想到以这种方式处理这个问题——这不是我脑海中建立隐喻的方式。谢谢! (我认为 forpas 下面的 FIRST_VALUE 是一个语法上更清晰的解决方案) 【参考方案1】:

这将获取每个子类别中的最高值,如果计数相同,则返回两个子类别:

select a.category, a.subcategory, itemcounts.total
from table a
cross apply ( select top 1 b.subcategory, count(b.item) as total
            from table b 
            where b.category = a.category
            group by b.subcategory
            order by count(b.item) desc) itemcounts
group by a.category, a.subcategory, itemcounts.total
having count(a.item) = itemcounts.total

【讨论】:

【参考方案2】:

这是一种处理关系的方法:

select * from (
   select category,Subcategory,rank() over (partition by category order by count(*) desc) rn 
   from tablename
   group by category,Subcategory
)t where rn = 1

db小提琴here

【讨论】:

【参考方案3】:

你可以用FIRST_VALUE()窗口函数来做到这一点:

SELECT DISTINCT Category,
       FIRST_VALUE(Subcategory) OVER (PARTITION BY Category ORDER BY COUNT(*) DESC) Subcategory
FROM tablename 
GROUP BY Category, Subcategory;

请参阅demo。

【讨论】:

哦,这很整洁

以上是关于T-SQL 查询获取子元素的最大值的主要内容,如果未能解决你的问题,请参考以下文章

T-SQL:在具有数字和字母的字符字段中获取最大数值

子查询 django 查询以从对象中获取最大的不同值并返回这些对象

我可以执行 T-SQL 查询来确定 SQL Server Express 实例的最大数据大小吗?

如何设置子查询以获取具有最新日期和最大 ID 的单个记录?

您将如何使用 T-SQL 获得满足条件的顺序/连续记录的最大/最大计数

查询以获取 table1 中每一行的结果,其中包含 N 个最大记录的子查询,找到满足 table2 中的条件