SQL 服务器:如何从 table 中删除部分空行

SQL Server: How to remove partially empty rows from table

我有一个奇怪的场景,无法在 google 中找到解决方案或在堆栈溢出中找到类似的问题:

这是我的 table:

table1(当前)

category col2  col3  col4  col5  col6  col7  col8  totalsum
--------------------------------------------------------------
a         12    25   null  null  null  null   null   
a         12    25    34   null  null  null   null   
b         57    93    72   63     99   null   null   
b         57    93    72   63     99   107    null   
b         57    93    72   63     99   107    32     

我需要删除部分/不完整的行并将更完整的行保存到新的 table 这样我的 table 现在就是这个(我需要保留最少的行空值数),但我无法过滤掉不完整的行并隔离更完整的行。

我需要的

category col2  col3  col4  col5  col6  col7  col8  totalsum
--------------------------------------------------------------
a         12    25    34   null  null  null   null   
b         57    93    72   63     99   107    32     

有人有什么想法吗?

谢谢

使用GROUP BY:

SELECT category,
       MAX(col2) AS col2,
       MAX(col3) AS col3,
       MAX(col4) AS col4,
       MAX(col5) AS col5,
       MAX(col6) AS col6,
       MAX(col7) AS col7,
       MAX(col8) AS col8,
       MAX(totalsum) AS totalsum
FROM yourTable
GROUP BY category

假设您可以接受每个类别每个列的最大非 NULL 值,这种方法会很有效。这个枢轴技巧之所以有效,是因为 SQL 服务器中的 MAX() 函数忽略了 NULL 值。

可能是这样的:

select * from table1 as t1 
where not exists(
                select 1 from table1 as t2 
                where(t1.id!=t2.id)and(t1.category=t2.category)
                and((t1.col1=t2.col1)or(is_null(t1.col1)and(not is_null(t2.col1))and...
                )

但是,因为您可以从 t1 和 t2 中排除相同的行,每行必须具有唯一的 ID,请参阅 (t1.id!=t2.id)。 主要思想 - 排除具有更多相关副本(更多非空字段)的行。

您可以尝试将这些列与 row_number():

一起排序
select *
from (
select *
, ROW_NUMBER() OVER (PARTITION BY category ORDER BY col2 desc, col3 desc, col4 desc, col5 desc, col6 desc, col7 desc, col8 desc) rn
from table1) i
where i.rn = 1

测试代码:

;WITH cte AS
(
SELECT 'a' category  ,12 col2 ,25 col3, null col4, null col5, null col6 ,null col7, null col8, 20 totalsum
UNION ALL SELECT 'a' ,12 ,25 ,34 ,null ,null ,null ,null ,20
UNION ALL SELECT 'b' ,57 ,93 ,72 ,63 ,99 ,null ,null ,50
UNION ALL SELECT 'b' ,57 ,93 ,72 ,63 ,99 ,107 ,null ,50
UNION ALL SELECT 'b' ,57 ,93 ,72 ,63 ,99 ,107 ,32 ,50
)
SELECT *
FROM (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY category ORDER BY col2 DESC, col3 DESC, col4 DESC, col5 DESC, col6 DESC, col7 DESC, col8 DESC) rn
FROM cte) i
WHERE i.rn = 1