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

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

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:

  1. --Oracle
  2. --For a given country, what city has the highest population? (where the country has more than one city)
  3. --Include the city name as a column.
  4. select
  5. country,
  6. count(*),
  7. max(population),
  8. any_value(city)
  9. keep (dense_rank first order by population desc)
  10. from
  11. cities
  12. group by
  13. country
  14. having
  15. 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:

  1. 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:

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

答案1

得分: 2

SQL Server没有实现这个功能。

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

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

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

  1. select
  2. country,
  3. count(*),
  4. max(population),
  5. SUBSTRING(MAX(FORMAT(population, 'D10') + city), 11, 8000)
  6. from
  7. cities
  8. group by
  9. country
  10. having
  11. 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)

  1. select
  2. country,
  3. count(*),
  4. max(population),
  5. SUBSTRING(MAX(FORMAT(population, &#39;D10&#39;) + city), 11, 8000)
  6. from
  7. cities
  8. group by
  9. country
  10. having
  11. 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:

确定