根据 Order By SQL 消除重复项

Eliminate duplicates based on Order By SQL

我有一个 table 超过 20 列和超过 300.000 行,其中与我的问题相关的列如下:

column1 |column2 |column3 | date
   123  |  657   | 2222   | 20 dec
   123  |  658   | 2222   | Null
   124  |  543   | 3333   | Null
   124  |  544   | 3333   | 1 Feb
   125  |  098   | 4444   | Null
   125  |  065   | 4444   | Null 

我执行了以下查询以根据需要对它们进行排序:

select * 
from table
order by column1,column2,date desc;

结果是:

column1 |column2 |column3 | date
   123  |  657   | 2222   | 20 dec
   123  |  658   | 2222   | Null
   124  |  544   | 3333   | 1 Feb
   124  |  543   | 3333   | Null
   125  |  065   | 4444   | Null
   125  |  098   | 4444   | Null 

主要目的是删除基于 column1 的重复行,如果它们的日期是 not null。如果他们都有 Null 那么我可以只保留一个。所以我要找的是这个:

column1 |column2 |column3 | date
   123  |  657   | 2222   | 20 dec
   124  |  544   | 3333   | 1 Feb
   125  |  065   | 4444   | Null

谁能帮我开发这个查询。我希望检索 ALL 其他列,而不仅仅是显示的列。

我正在使用 Azure SQL,它基本上是 SQL 服务器

我试过这样做:

SELECT * FROM table AS main
WHERE main.column4 IN
(SELECT sub.MinID FROM
   (SELECT column1, column3, min(column4) As MinID
    FROM table
    GROUP BY column1, column3) AS sub)
ORDER BY main.column1, main.column3;

问题在于,由于规则是 min(column4),当我有一个 Not Nullcolumn4 值小于另一个时,它选择 NULL。我尝试放置 min(date) 但出现此错误: Arithmetic overflow error converting expression to data type smalldatetime 我猜是因为 Null 值。

如何输入规则,如果一个是Not null,另一个是Null然后选择Not Null

试试这个:

Select * from table t
Where (date is not null
    and not exists 
     (select * from table 
      where date is Null
         and column1 = t.Column1)) Or
   column2 = 
     (Select Max(column2) from table
      Where column1 = t.Column1)

看起来很经典top-n-per-group。一种方法是使用 ROW_NUMBER:

WITH
CTE
AS
(
    SELECT
        column1
        ,column2
        ,column3
        ,dt
        ,ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY dt desc, column2) AS rn
    FROM tbl
)
SELECT
    column1
    ,column2
    ,column3
    ,dt
FROM CTE
WHERE rn = 1
ORDER BY
    column1
;

PARTITION BY column1 表示行编号在 column1 更改时重新开始。 ORDER BY dt desc, column2 确定行编号时的顺序。最后,您只需使用 WHERE rn = 1.

选择分区的第一行

最终结果每个 column1 只有一行,因此向最终 ORDER BY 添加更多列不会改变任何内容。

CTE 可能是您最好的选择:

WITH CTE
AS (
    SELECT column1
        ,column2
        ,column3
        ,DATE
        ,ROW_NUMBER() OVER (
            PARTITION BY column1 ORDER BY 
                date
                ,column1
                ,column2
                ,column3 DESC
            ) AS RN
    FROM table
    )
DELETE
FROM CTE
WHERE RN <> 1

要检查您要删除的数据是否正确,只需在末尾将 DELETE 更改为 SELECT *。