【问题标题】:Eliminate row that has null value using CTE使用 CTE 消除具有空值的行
【发布时间】:2023-03-27 13:48:01
【问题描述】:

我有一些数据

RowIdentifier   ID  RowID   Position    Data    Rn
1             1      1       a1          A1      1
2             1      2       a2          A2      1
3             1      3       a3          NULL    1
4             1      4       a3          A3      2
5             1      1       b1          B1      1
6             1      2       b2          NULL    1
7             1      3       b2          B2      2
8             1      4       b3          B3      1

想要的输出是

ID  RowID  Position  Data
1     1     a1       A1
1     1     b1       B1
1     2     a2       A2
1     2     b2       B2
1     3     a3       A3
1     3     b3       B3

我需要消除那些位置重复且数据为空的行。即在示例中,在 RowIdentifier 3 和 4 中,Position 列中的值为 a3,但第三条 RowIdentifier 记录不会出现在最终输出中,因为它在 Data 列中为 null。

ddl如下

Declare @t table(RowIdentifier int identity,ID int,RowID int,Position varchar(10),Data varchar(10),Rn int)
    Insert into @t
    Select 1,1,'a1','A1',1 union all
    Select 1,2,'a2','A2',1 union all
    Select 1,3,'a3',null,1 union all
    Select 1,4,'a3','A3',2 union all
    Select 1,1,'b1','B1',1 union all
    Select 1,2,'b2',null,1 union all
    Select 1,3,'b2','B2',2 union all
    Select 1,4,'b3','B3',1 

    Select * from @t

我的方法如下

;with cte as(
Select ID,RowID,Position,Position as p2,Data,RowIdentifier from @t
union all
select c4.ID,c4.RowID,c4.Position,c5.Position , c4.Data,c4.RowIdentifier
from cte c5
join @t c4 on c4.Position = c5.Position
where c5.RowIdentifier < c4.RowIdentifier
 )
 ,
 cte2 as(
 select * , rn = Row_Number() over(PARTITION by position order by RowIdentifier)
 from cte where Data is not null)

select ID,RowID,Position,Data from cte2 where rn =1

但未按预期输出工作。我的输出是

ID  RowID   Position    Data
1   1   a1  A1
1   2   a2  A2
1   4   a3  A3
1   1   b1  B1
1   3   b2  B2
1   4   b3  B3

需要帮助

谢谢

【问题讨论】:

  • 递归调用 CTE 时需要终止条件。 IE。 WHERE something &lt; somethingelse
  • 我已经更新了我的查询,但是虽然我很接近,但输出并不像预期的那样......如果你能指出我的查询中的错误,将不胜感激
  • 为什么要“RowID”与原始 RowID 无关?它应该是不同的列名,并且 RowID 不应出现在输出中。这是误导

标签: sql-server sql-server-2005 tsql common-table-expression


【解决方案1】:

试试这个代码

Select 
    ID,
    dense_rank() over(order by substring(data,2,len(data))*1) as rowid,
    position,
    data 
from 
    @t 
where 
    data is not null
group by 
    ID,RowID,position,data

【讨论】:

    【解决方案2】:

    过滤后的简单聚合

    SELECT
       ID, MIN(RowID) AS RowID, POSITION, Data
    FROM
       @t
    WHERE
       Data IS NOT NULL
    GROUP BY
       ID, RowID, POSITION, Data
    ORDER BY
       POSITION, RowID
    

    这会保留原始数据集中的 RowID,这样会更正确

    3             1      3       a3          NULL    1
    4             1      4       a3          A3      2   --take this row
    

    【讨论】:

    • 如果我正确理解了这个问题,我们只想在结果集中已经有具有相同“位置”值的非空值时省略空值
    • @Tao:本案例没有样本数据。根据我们所知道的,我们可以合理地假设 NULL 只发生在我们有重复的地方......
    猜你喜欢
    • 2019-07-13
    • 1970-01-01
    • 2017-04-02
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多