SQL Server equivalent to Oracle's ANY_VALUE(…) KEEP (DENSE_RANK FIRST/LAST ORDER BY …)

huangapple go评论67阅读模式
英文:

SQL Server equivalent to Oracle's ANY_VALUE(...) KEEP (DENSE_RANK FIRST/LAST ORDER BY ...)

问题

以下是翻译好的内容:

"Is there equivalent functionality in SQL Server?" -> "SQL Server中是否有类似的功能?"

英文:

There's a technique in Oracle SQL that can be used to simplify aggregation queries.

Scenario: We've aggregated on a particular column — but we actually want to know information from a different column.

There are a number of ways to achieve that using SQL. I'm looking for a solution that lets me do it in a calculated column -- all within a single SELECT query (no subqueries, joins, WITH, etc.).

Like this:

--Oracle
--For a given country, what city has the highest population? (where the country has more than one city)
--Include the city name as a column.
select
    country,
    count(*),
    max(population),
    any_value(city)
        keep (dense_rank first order by population desc)
from
    cities
group by
    country
having
    count(*) > 1

db<>fiddle

As shown above, the following column can bring in the city name, even though the city name isn't in the GROUP BY:

 any_value(city) keep (dense_rank first order by population desc)

Is there equivalent functionality in SQL Server?


Related:


Edit:

I changed MAX() to ANY_VALUE(), since I think ANY_VALUE() is easier to read.

Ties can be broken by adding , city desc to the order by, making it deterministic:

any_value(city) keep (dense_rank first order by population desc, city desc)

答案1

得分: 2

SQL Server没有实现这个功能。

我正在寻找一个让我可以在一个计算列中完成的解决方案
-- 全部在单个SELECT查询内(没有子查询、连接、WITH等)。

这是可能的,但不太美观(DB Fiddle)。

假设人口是正整数,那么您可以使用以下方法(请参考基于连接的解决方案,了解此方法背后的思路):

select
    country,
    count(*),
    max(population),
    SUBSTRING(MAX(FORMAT(population, 'D10') + city), 11, 8000)
from
    cities
group by
    country
having
    count(*) > 1
英文:

SQL Server does not implement this.

> I'm looking for a solution that lets me do it in a calculated column
> -- all within a single SELECT query (no subqueries, joins, WITH, etc.)

It's possible but not pretty (DB Fiddle).

Assuming population is a positive integer then you could use the below (See Solution Based on Concatenation for the idea behind this approach)

select
    country,
    count(*),
    max(population),
	SUBSTRING(MAX(FORMAT(population, &#39;D10&#39;) + city), 11, 8000)
from
    cities
group by
    country
having
    count(*) &gt; 1

huangapple
  • 本文由 发表于 2023年3月4日 03:26:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定