【问题标题】:Filtering by RANK() in HAVING clause without subqueries在没有子查询的 HAVING 子句中按 RANK() 过滤
【发布时间】:2017-11-02 19:11:00
【问题描述】:

我正在获取分组最大值(data CTE 模拟一组来自实际表的连接):

with data as (
    select 'Austria' as country, 1 as id, 'red' as colour, 120 as quantity
    union all select 'Austria', 2, 'green', 96
    union all select 'Austria', 3, 'blue', 103

    union all select 'Belgium', 1, 'red', 33
    union all select 'Belgium', 2, 'green', 12
    union all select 'Belgium', 3, 'blue', 40
)
select country, colour, quantity
from (
    select country, colour, quantity,
    rank() over (partition by country order by quantity desc, id) as position
    from data
    group by country, id, colour, quantity
) subquery
where position=1;

这很好用,但我不得不在子查询中使用 RANK() 调用来包装查询,因为这种替代方法会触发语法错误:

-- [...]
select country, colour, quantity,
rank() over (partition by country order by quantity desc, id) as position
from data
group by country, id, colour, quantity
having rank() over (partition by country order by quantity desc, id)=1;

窗口函数只能出现在 SELECT 或 ORDER BY 子句中。

是否有替代语法来避免此限制或子查询是唯一明智的方法?

最终目标是将此代码集成到更大的动态生成的 SQL 表达式集中。如果我可以保留一个查询,我可以用数组定义不同的部分(选择、连接表、位置、分组依据、拥有和排序依据)。否则我需要考虑进行重大改写。

【问题讨论】:

    标签: sql sql-server sql-server-2008-r2


    【解决方案1】:

    您可以使用前 1 名,如下所示

    select top (1) with ties country, colour, quantity,
        rank() over (partition by country order by quantity desc, id) as position
    from data
    --group by country, id, colour, quantity
    order by rank() over (partition by country order by quantity desc, id)
    

    【讨论】:

    • 加1,但我认为group by country, id, colour, quantity是多余的
    • 是的,我们不需要冗余的分组
    • 尽管 top (1) with ties 更优雅,但它使用额外的排序运算符,如果您有大量数据,这会有点昂贵
    • 谢谢,这应该与底层框架很好地集成。 GROUP BY 子句是代码编辑的剩余部分。
    【解决方案2】:

    如果您查看性能差异,我仍然觉得子查询方法比上面的顶部 (1) 方法更好,因为下面的排序运算符:

    尽管 top (1) with ties 更优雅...下面是基于执行计划快照的性能差异

    【讨论】:

    • 我没有经验或知识来判断一个 100% 的排序是否比两个 50% 的排序更好或更差,但我理解你的整体观点。此外,TOP 1 WITH TIES 方法可能更脆弱,因为如果我将更多列附加到 ORDER BY 子句,它很容易中断。
    • 如果您看到“查询成本(相对于批次):”对于第一个查询,它只占用了 33%,而对于第二个带有“Top (1) with ties”的查询,它占用了 67%,如果我们单独分析它是一个额外的排序运算符...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2021-08-17
    • 2019-11-10
    • 1970-01-01
    相关资源
    最近更新 更多