T-SQL 按问题分组

发布于 2024-10-14 12:12:00 字数 561 浏览 8 评论 0原文

我遇到了以下问题(或者可能只是思维障碍):

我有一个表(实际上是表中的视图),其中包含以下列和数据:

https://i.sstatic.net/n98Sw.png

现在我想按“Customer”列对这些数据进行分组,并获取具有最高“CompetitorCount”的“CompetitorName”。 当然,我可以创建这样的查询:

SELECT 客户,MAX(CompetitorCount) FROM MyTable GROUP BY 客户

这将返回两行:

Foo; 12  
Bar; 7

但我无法以这种方式获取 CompetitorName。如果我将其包含到分组部分中,“客户”将出现多次。否则我必须使用聚合函数来选择我想要使用的“CompetitorName”,但当然 MAX 不起作用。

我确信这可以以某种方式完成,但目前我不知道如何完成。

预先感谢您的任何帮助。

I've got the following Problem (or maybe just a thinking barrier):

I've got a table (actually a view from a table) with the following columns and data:

https://i.sstatic.net/n98Sw.png

Now i want to Group this data by the column "Customer" and get the "CompetitorName" with the highest "CompetitorCount".
Of course i can create a query like this:


SELECT Customer, MAX(CompetitorCount) FROM MyTable GROUP BY Customer

This will return two rows:

Foo; 12  
Bar; 7

But i wont be able to get the CompetitorName that way. If I include it into the group by section, the "Customer" will show up multiple times. Otherwise I have to use an aggregate function to select which "CompetitorName" I want to use, but of course MAX doesnt work.

I'm sure this can be done somehow, but at the moment i've got no idea how.

Thanks in advance for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紫﹏色ふ单纯 2024-10-21 12:12:00
select customer, competitorname, competitorcount
FROM
(
 select *, rn = ROW_NUMBER() over (
  partition by customer order by competitorcount desc)
 from tbl
) X
WHERE rn=1

如果要显示最大值处的 TIES,请将 ROW_NUMBER() 更改为 RANK()。

您甚至可能会发现交叉应用版本更快,但它不适用于领带。如果竞争对手之间存在平局,TOP 1 确保单一记录。

select C.*
FROM
(select distinct customer from tbl) A
cross apply
(select top 1 B.*
 from tbl B
 where A.customer = B.customer
 order by B.competitorcount desc) C

它首先选择所有不同的客户。然后,对于每个客户,它会启动并检索该客户的 MAX(竞争对手计数)记录。

select customer, competitorname, competitorcount
FROM
(
 select *, rn = ROW_NUMBER() over (
  partition by customer order by competitorcount desc)
 from tbl
) X
WHERE rn=1

If you want to show TIES at the Max value, change ROW_NUMBER() to RANK().

You might even find the cross apply version faster, but it doesn't work for ties. TOP 1 ensures a single record if there are ties among the competitors.

select C.*
FROM
(select distinct customer from tbl) A
cross apply
(select top 1 B.*
 from tbl B
 where A.customer = B.customer
 order by B.competitorcount desc) C

It first selects all the distinct customers. Then for each customer, it goes off and retrieves the records with the MAX(competitorcount) for that customer.

不奢求什么 2024-10-21 12:12:00

有几种方法可以做到这一点,但最直接的方法是:

WITH Custs AS (
   SELECT 
      Customer, 
      CompetitorName,
      CompetitorCount,
      ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY CompetitorCount DESC) AS __ROW
   From MyTable
)
SELECT
    Customer,
    CompetitorName,
    CompetitorCount
FROM Custs
WHERE __ROW = 1;

如果您想要平局(最高计数与客户平局,并且您想要指定两行),请使用 RANK() 而不是 ROW_NUMBER()

您还可以使用自连接来执行此操作:

WITH Custs AS (
    SELECT Customer, MAX(CompetitorCount) AS CompetitorCount
    FROM MyTable 
    GROUP BY Customer)
SELECT m.Customer, m.CompetitorName, m.CompetitorCount
FROM MyTable m
INNER JOIN Custs c
   ON  c.CompetitorCount = m.CompetitorCount
   AND c.Customer        = m.Customer;

There are a couple of ways to do this, but the most straightforward way is:

WITH Custs AS (
   SELECT 
      Customer, 
      CompetitorName,
      CompetitorCount,
      ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY CompetitorCount DESC) AS __ROW
   From MyTable
)
SELECT
    Customer,
    CompetitorName,
    CompetitorCount
FROM Custs
WHERE __ROW = 1;

and if you want ties (where the highest counts tie for a customer, and you want to specify both rows), use RANK() instead of ROW_NUMBER() in the above query.

You could also do this using a self-join:

WITH Custs AS (
    SELECT Customer, MAX(CompetitorCount) AS CompetitorCount
    FROM MyTable 
    GROUP BY Customer)
SELECT m.Customer, m.CompetitorName, m.CompetitorCount
FROM MyTable m
INNER JOIN Custs c
   ON  c.CompetitorCount = m.CompetitorCount
   AND c.Customer        = m.Customer;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文