【问题标题】:SQL oracle Select condition in groupSQL oracle 在组中选择条件
【发布时间】:2016-03-18 13:15:00
【问题描述】:

假设我有一个包含 3 列的表格:

ID | GroupId | DateCreatedOn |

我想选择按 GroupId 分组的数据,所以:

select GroupId from tableName group by GroupId;

但是如果我想对每个组执行另一个选择呢?现在假设我想要每个组的最后创建的行 (DateCreatedOn)?

另外,我想检索所有列,而不仅仅是 GroupId。

我有点迷茫,因为我只有 GroupId 可用。

请提供一些解释,而不仅仅是正确的查询。

【问题讨论】:

  • 添加一些示例表数据,结果是预期的。
  • 一般 GROUP BY 提示,选定的列应该是集合函数(例如 AVG)的参数,或者列在 group by 子句中。 (很少同时使用。)

标签: sql oracle


【解决方案1】:

您可以为此使用ROW_NUMBER

SELECT ID, GroupId, DateCreatedOn
FROM (
  SELECT ID, GroupId, DateCreatedOn,
         ROW_NUMBER() OVER (PARTITION BY GroupId 
                            ORDER BY DateCreatedOn DESC) AS rn
  FROM mytable) t
WHERE t.rn = 1

对于每个GroupId 分区中具有最新DateCreatedOn 值的记录,rn 字段等于 1。

【讨论】:

  • 我删除了我的评论,因为我的查询有误。您的查询将我引向stackoverflow.com/questions/10477085/…,在那里我可以找到关于 Partition by 的一个很好的解释。谢谢
【解决方案2】:

您可以在聚合中使用KEEP ( DENSE_RANK [FIRST|LAST] ORDER BY ... ) 获取另一列的最大值:

SELECT   GroupID,
         MAX( ID ) KEEP ( DENSE_RANK LAST ORDER BY DateCreatedOn ) AS id
         MAX( DateCreatedOn ) AS DateCreatedOn
FROM     table_name
GROUP BY GroupId

您也可以使用ROW_NUMBER()

SELECT ID,
       GroupID,
       DateCreatedOn
FROM   (
  SELECT t.*,
         ROW_NUMBER() OVER ( PARTITION BY GroupID
                             ORDER BY DateCreatedOn DESC, ID DESC ) AS RN
  FROM   table_name t
)
WHERE  RN = 1

(ID DESC 被添加到 ORDER BY 以获得最大的 ID 以获得最新的 DateCreatedOn 以提供与第一个查询相同的结果;如果您没有确定性顺序,那么您可能会得到数据库首先生成的任何行,结果可能是不确定的)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 2019-12-09
    • 2022-12-20
    • 1970-01-01
    • 2019-01-15
    • 2020-05-29
    • 2012-10-16
    相关资源
    最近更新 更多