根据 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 Null
的 column4
值小于另一个时,它选择 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 *。
我有一个 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 Null
的 column4
值小于另一个时,它选择 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 *。