在给定条件下删除所有行-SQL

user_id  date         fieldid  fieldvalue  fromvalue Tovalue action 
1        2020-01-01     1         a         NULL      0        C
2        2020-01-01     1         a         NULL      0        C
2        2020-01-01     1         a         NULL      0        N
2        2020-01-02     1         a         NULL      0        C

当前cte查询已返回此值。我试图删除给定日期,fieldid,fieldvalue的用户的条目action = c和action = N。在这种情况下,必须返回第一行和最后一行。第二行和第三行必须删除,因为其中一行中的一个为N。

不知道在这种情况下如何在self-join或cte内添加删除条件。任何帮助深表感谢。谢谢

评论
  • yalias
    yalias 回复

    您可以使用窗口函数来过滤所需的行:

    select t.*
    from (select cte.*,
                 sum(case when action = 'N' then 1 else 0 end) over (partition by user_id, date) as n_cnt
          from cte
         ) t
    where n_cnt = 0;
    

    您也可以编写没有窗口功能的代码:

    select cte.*
    from cte
    where not exists (select 1
                      from cte cte2
                      where cte2.user_id = cte.user_id and
                            cte2.date = cte.date and
                            cte2.action = 'N'
                     );
    

    但是,它有两个对CTE的引用,并且性能可能很差-因为SQL Server将为每个引用重复CTE的逻辑。