SQL:删除GroupBy中的所有NOT MAX记录

时间:2013-01-10 19:09:07

标签: sql

我的目标是删除我的表中不是分组CaseKey的MAX(recordDate)的所有记录。因此,如果我有3组3个casekeys的9条记录,并且每个casekey有3个日期。我会删除每组的2个较低日期,并得出3个总记录,只剩下每个记录的MAX(recordDate)。

我有以下SQL查询:

    DELETE FROM table
    WHERE tableID NOT IN (
    SELECT tableID
    FROM (
    Select MAX(recordDate) As myDate, tableID From table
    Group By CaseKey
    ) As foo
    )

我收到错误: 第3行出错...列'table.tableID'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

显然我可以将tableID添加到Group By子句中,但是该语句的结果不正确并返回所有行而不是仅返回分组CaseKeys的MAX recordDate。

服务器现在已经关闭,但明显的答案是:(来自WildPlasser答案的微小调整)

DELETE zt FROM ztable zt
WHERE EXISTS (
    SELECT * FROM ztable ex
    WHERE ex.CaseKey = zt.CaseKey
    AND ex.recordDate > zt.recordDate
);

换句话说,对于zt中的每个记录,运行一个查询以查看同一记录是否也有一个记录具有更高的recordDate。如果是,则WHERE EXISTS语句通过并删除记录,否则WHERE语句失败,记录是其自己的MAX记录日期。

感谢WildPlasser,因为这种简单化的方法让我感到有些不知所措。

3 个答案:

答案 0 :(得分:22)

MAX有一个特殊属性:没有值高于max的记录。因此,我们可以删除具有相同CaseKey但具有更高recordDate的记录的所有记录:

DELETE FROM ztable zt
WHERE EXISTS (
    SELECT *
    FROM ztable ex
    WHERE ex.CaseKey = zt.CaseKey
    AND ex.recordDate > zt.recordDate
    );

BTW:上述查询(以及MAX()版本)假设只有一条记录具有最大日期。可能会有联系。

对于tie,你需要在where子句中添加一个额外的字段;作为决胜局。假设TableId可以这样运行,查询将变为:

DELETE FROM ztable zt
WHERE EXISTS (
    SELECT *
    FROM ztable ex
    WHERE ex.CaseKey = zt.CaseKey
    AND (   ex.recordDate > zt.recordDate
        OR (ex.recordDate = zt.recordDate AND ex.TableId > zt.TableId)
        )
    );

答案 1 :(得分:6)

快递

  

从我的表中删除不是a的MAX(recordDate)的所有记录   分组CaseKey

在sql中作为

DELETE FROM table t1
WHERE t1.recordDate <> 
  (SELECT MAX(recordDate)
   FROM table t2
   WHERE t2.CaseKey = t1.CaseKey)

答案 2 :(得分:1)

您可以排名具有相同caseKey的所有记录,其中等级&gt; 1只返回较低的日期。这样你可以使用你的tableID

DELETE FROM [table]
WHERE [tableID] IN
  (SELECT
    [sub].[tableID]
  FROM
  (
    SELECT 
      [tableID],
      Rank() OVER (PARTITION BY [caseKey] ORDER BY [recordDate] DESC, [tableID] DESC) AS [rank]
    FROM [table]
  ) AS [sub]
  WHERE [sub].[rank] > 1)