2

我需要编写的 SQL 只保留表中每个可识别记录的最少 5 条记录。为此,我使用partition by并删除了返回值大于 5 的所有记录。当我尝试在与partition by语句相同的查询中使用 WHERE 子句时,我收到错误“WHERE 子句中不允许使用有序分析函数”。所以,为了让它工作,我必须使用三个子查询。我的 SQL 看起来像这样:

delete mydb.mytable where (field1,field2) in
(
    select field1,field2 from
    (
        select field1,field2,
        Rank() over
        (
            partition BY field1
            order by field1,field2
        ) n 
        from mydb.mytable
    ) x
    where n > 5
)

最里面的子查询只返回原始数据。因为我不能在那里使用 WHERE,所以我用一个子查询包装了它,其目的是 1)使用 WHERE 获取排名大于 5 的记录,以及 2)只选择 field1 和 field2。我只选择这两个字段的原因是我可以使用 IN 语句删除最外层查询中的那些记录。

它可以工作,但看起来有点麻烦。我想将内部的两个子查询合并为一个子查询。这可能吗?

4

1 回答 1

1

听起来您需要使用Window Aggregate 函数QUALIFYHAVING子句。以下是我对您要完成的工作的看法。

请不要在未先测试之前直接针对您的生产数据运行此 SQL。

/* Physical Delete */
DELETE TGT
  FROM MyDB.MyTable TGT
 INNER JOIN
       (SELECT Field1
             , Field2
        FROM MyDB.MyTable
        QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
              > 5
       ) SRC
    ON TGT.Field1 = SRC.Field1
   AND TGT.Field2 = SRC.Fileld2

/* Logical Delete */
UPDATE TGT
  FROM MyDB.MyTable TGT
     ,
       (SELECT Field1
             , Field2
        FROM MyDB.MyTable
        QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
              > 5
       ) SRC
   SET Deleted = 'Y'
    /* RecordExpireDate = Date - 1 */
 WHERE TGT.Field1 = SRC.Field1
   AND TGT.Field2 = SRC.Fileld2
于 2012-12-06T19:25:35.410 回答