我有一个包含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 Server
我试过这样做:
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
的{{1}}值小于另一个时,{@ 1}}选择column4
。我尝试了NULL
,但是我收到了这个错误:
min(date)
我猜是因为Arithmetic overflow error converting expression to data type smalldatetime
值。
如何输入规则Null
而另一个Not null
然后选择Null
答案 0 :(得分:2)
看起来像经典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
添加更多列不会改变任何内容。
答案 1 :(得分:0)
试试这个:
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)
答案 2 :(得分:0)
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 *。