【问题标题】:How to order values inside group by如何在 group by 中排序值
【发布时间】:2011-06-22 01:41:59
【问题描述】:

考虑以下 SQL Server 表:

  ID  |   X   |   Y
------+-------+-------
   1  |   1   |   1
   2  |   1   |   2
   3  |   1   |   3
   4  |   2   |   40
   5  |   2   |   500
   6  |   3   |   1
   7  |   3   |   100
   8  |   3   |   10

我需要选择Y按x分组的最大值的行的ID,即:

  ID  |   X   |   Y
------+-------+-------
   3  |   1   |   3
   5  |   2   |  500
   7  |   3   |  100

查询将嵌套多次,因此需要最佳性能解决方案...

【问题讨论】:

  • 你写了“MS SQL”,但用“mysql”标记了它,我将为 MySQL 给出答案(也许对 MS SQL 也有效)。
  • 没问题,我会尝试翻译成MS SQL...
  • 那么我的链接给你三个解决方案。看,我们甚至在 Stack Overflow 上也有一个标签。 ;)
  • @AndreKR:如果我没记错的话,greatest-n-per-group 的意思是“每组最多的 N 个项目”。
  • 根据stackoverflow.com/tags/greatest-n-per-group/info,标签适用于这两种情况。

标签: sql sql-server greatest-n-per-group


【解决方案1】:

设置:

 declare @MyTable table(ID int, X int, Y int)

 insert @MyTable
 values
    (   1  ,   1   ,   1),
    (   2  ,   1   ,   2),
    (   3  ,   1   ,   3),
    (   4  ,   2   ,   40),
    (   5  ,   2   ,   500),
    (   6  ,   3   ,   1),
    (   7  ,   3   ,   100),
    (   8  ,   3   ,   10)

查询:

;with cte
as
(
    select *, row_number() over(partition by X order by Y desc) RowNumber
    from @MyTable
)
select Id, X, Y
from cte
where RowNumber = 1

结果:

Id          X           Y
----------- ----------- -----------
3           1           3
5           2           500
7           3           100

查询适用于 MS SQL 2005+。 该设置将在 MS SQL 2008+ 中运行。

【讨论】:

  • @Denis Yaremov - 我很困惑。你有 MySQL 或 MS SQL 吗?帖子以Consider the following MS SQL Server table 开头。我问的原因是因为如果您有 MS SQL,那么 cte 查询对您来说将是更有效的解决方案。如果您比较执行计划,您可以看到这一点。
  • @Denis Yaremov - 您要求最佳性能解决方案,但选择了不是最佳性能解决方案的答案:)。
  • 嗨,Alex,我应该说我选择的解决方案根本没有按我的预期工作,我没有选择你的解决方案,因为我不明白它是如何工作的正在工作...
【解决方案2】:

是的,这种类型的问题很多次...添加关键字“STRAIGHT_JOIN”以通过首先强制执行“PreQuery”来预优化查询。

select STRAIGHT_JOIN
      YT.*
   from 
      ( select x, max(y) HighPerX
           from YourTable 
           group by x ) PreQuery
      join
         YourTable YT
            on PreQuery.X = YT.X 
            AND PreQuery.HighPerX = YT.y

【讨论】:

  • 在 MS SQL 中,这会比 cte 效率低。
  • @Alex Aza,好的,这是通用的,几乎适用于所有数据库——正如海报所提到的,它们正在运行 MySQL。
【解决方案3】:

【讨论】:

  • 使用不相关的查询似乎是合乎逻辑的解决方案,但我认为通过身份(字段)以外的字段进行连接是不好的做法..
  • 我不会将其称为不好的做法(这就是它们被称为 关系 数据库的原因),但除非您使用小型数据集,否则它通常性能不佳。
  • 至少在 MySQL 中,通过主键加入并不比通过任何其他索引列加入慢或快。然而,由于 MySQL 的优化器很差,使用子查询可能会更慢,这就是为什么它也提供了两种没有子查询的解决方案。
【解决方案4】:

【讨论】:

  • 这绝对是有用的链接
猜你喜欢
  • 2011-11-18
  • 2022-01-10
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 2011-05-25
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多