【问题标题】:T-SQL, how to get top three maximum values and if repeats, include them?T-SQL,如何获得前三个最大值,如果重复,包括它们?
【发布时间】:2021-11-16 22:06:10
【问题描述】:

如标题所述,我希望选择前 3 个值,如果计数的值重复,也包括它。

SELECT b.planID, count(b.planID) AS PopularPlan
FROM dbo.Subscriber as b
GROUP BY B.planID
ORDER BY count(b.planID) DESC;

此输出返回所有最大值,例如:

PlanID  PopularPlan
 101    2555
 123    2555
 432    2390
  23    2390
  45    2090
  12    2080
  55    2090

如果我使用 TOP 3,选择 TOP 3,使用以下 SQL:

SELECT TOP 3 b.planID, count(b.planID) AS PopularPlan
FROM dbo.Subscriber as b
GROUP BY B.planID
ORDER BY count(b.planID) DESC;

它将返回以下内容:

PlanID  PopularPlan
 101    2555
 123    2555
 432    2390

在这种情况下,期望的输出是做我想做的事情:

PlanID  PopularPlan
     101    2555
     123    2555
     432    2390
      23    2390
      45    2090

我了解 TOP 3 仅限于三个结果,但我似乎无法弄清楚如何添加重复的方法。

此外,如果我要加入 WITH TIES:

SELECT TOP 3 WITH TIES b.planID, count(b.planID) AS PopularPlan
FROM dbo.Subscriber as b
GROUP BY B.planID
ORDER BY count(b.planID) DESC;

这种情况下的输出是:

PlanID  PopularPlan
     101    2555
     123    2555
     432    2390
      23    2390

在测试时,如果我选择 TOP 5,则会出现 2090 值,但我希望尽可能对 TOP 3 执行相同操作,以便输出保持原样:

PlanID  PopularPlan
     101    2555
     123    2555
     432    2390
      23    2390
      45    2090 <- has to have this value too

【问题讨论】:

  • where planid in (select top(3) planid from t group by... order by...)?

标签: sql tsql


【解决方案1】:

DENSE_RANK() 是你的朋友:

WITH cteOriginal AS
(
    SELECT b.planID, count(b.planID) AS PopularPlan
    FROM dbo.Subscriber as b
    GROUP BY B.planID
)
, cteDenseRank AS
(
    SELECT *, DENSE_RANK() OVER( ORDER BY PopularPlan DESC) AS DRank
    FROM cteOriginal
)
SELECT planID, PopularPlan
FROM cteDenseRank
WHERE DRank <= 3
ORDER BY PopularPlan DESC
;

大概你可以将两个 CTE 合并在一起,但我不确定 OVER 函数如何与 GROUP BY 交互,所以我这样做的时间稍长。

我个人可以说,自从 ROW_NUMBER()、RANK() 和 DENSE_RANK() 窗口函数出现在 T-SQL(2008 年?)之后,我几乎不再使用 TOP。

已编辑 - DENSE_RANK() 以显示最佳结果。

【讨论】:

  • @Marius 抱歉,将原始查询的 ORDER BY 子句移到最终 SELECT 语句的末尾(但在“;”之前)。我也会编辑我的答案......好的,我已经更正了。
  • 等待 ... 发现另一个错字。现在应该好了。好的,语法检查器现在接受它。
  • 我已对最后一行 (ORDER BY) 进行了更改,以修复最近的错误。但是,我无法真正对此进行测试,因为我没有表格或原始数据。
  • @Marius 是的。我已经制作了一些测试数据和表格,问题是我忽略了您原始 ORDER BY 中的 DESC,我还必须将其添加到 DENSE_RANK() 中......好吧,我已经将 DENSE_RANK() 更改为 @987654322 @ 这在我的测试中似乎确实有效。
  • 谢谢,问题已解决。这是一次学习经历。我非常感激!谢谢!
猜你喜欢
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 2015-06-23
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多