在没有子查询的HAVING子句中按RANK()过滤

Álv*_*lez 5 sql sql-server sql-server-2008-r2

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

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;
Run Code Online (Sandbox Code Playgroud)

这工作正常但我不得不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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

Kan*_*amy 10

你可以使用前面带有关系的前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)
Run Code Online (Sandbox Code Playgroud)


Kan*_*amy 5

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

尽管带有联系的顶部(1)更优雅...以下是基于执行计划快照的性能差异

在此输入图像描述