如果重复存在,则SQL Server忽略行,除非id存在

时间:2018-11-05 18:05:35

标签: sql sql-server

我运行以下SQL查询并获得以下行作为输出:

material.diffuse.wrapT = .mirror


SELECT EventTime
      ,UserID
      ,SubAddr
FROM tablename
WHERE EventType = 20 AND 
    (SubAddr = 1 OR SubAddr = 2)

我想以这样的方式更改查询,即它只获取subaddr 1和2的每个用户获得第一个事件时间的行。如果存在另一行,其中subaddr为1,则该行之后为相同的userID和subaddr = 2我也希望它也检索该行。

请参见以下示例

 EventTime  UserID  SubAddr 

2018-05-04 16:47:56.000 113 1    
2018-05-04 16:48:45.000 113 2    
2018-05-04 16:49:17.000 113 1    
2018-05-04 16:49:27.000 113 2    
2018-05-04 16:49:48.000 113 1    
2018-05-04 16:49:57.000 113 2    
2018-05-04 16:50:15.000 113 1    
2018-05-04 16:51:01.000 113 2    
2018-05-04 16:51:23.000 113 1    
2018-05-04 16:51:33.000 113 2    
2018-05-07 15:42:13.000 114 1    
2018-05-07 15:42:16.000 114 1    
2018-05-07 15:42:26.000 114 1    
2018-05-07 15:42:35.000 114 2    
2018-05-07 15:42:43.000 114 2    
2018-05-07 15:42:54.000 114 1    
2018-05-07 15:43:02.000 114 1    
2018-05-07 15:43:11.000 114 2    
2018-05-07 15:43:20.000 114 2    
2018-05-07 15:43:35.000 114 1    
2018-05-07 15:43:42.000 114 1    
2018-05-07 15:43:51.000 114 2    
2018-05-07 15:43:58.000 114 2

我希望这个例子更清楚。我整天都在为此苦苦挣扎,却找不到答案

2 个答案:

答案 0 :(得分:0)

Lee Mac解决方案不适用于我,因为您只需要在此表中输入

2018-05-07 15:42:13.000 114 1  <- This row    

2018-05-07 15:42:35.000 114 2  <- This row   

因为您是从user和subAddr的分组运算符中选择一个分钟。

我有一个简单的解决方案(但是您必须检查数据的完整性才能正常工作) 以这种方式剪切数据:

2018-05-07 15:42

并使用此查询

SELECT distinct(EventTime, UserID, SubAddr)
FROM tablename 
WHERE EventType = 20 AND (SubAddr = 1 OR SubAddr = 2)

通过这种方式,您将获取以下数据:

2018-05-07 15:42:13.000 114 1  <- This row    

2018-05-07 15:42:35.000 114 2  <- This row    

2018-05-07 15:42:54.000 114 1  <- This row    
2018-05-07 15:43:02.000 114 1  <- Not this row (this will capture) 

2018-05-07 15:43:11.000 114 2  <- This row   

2018-05-07 15:43:35.000 114 1  <- This row    


2018-05-07 15:43:51.000 114 2  <- This row 

这是一种快速的方法,否则您需要进行嵌套查询,这将更加复杂。

但是我重复一遍,这不是解决您的问题的方法,只是很短的路程。

答案 1 :(得分:0)

使用lag()

with t as (
      select t.*, lag(subaddr) over (partition by userid order by eventtime) as prev_subaddr
      from tablename t
      where EventType = 20 and SubAddr in (1, 2)
    )
select EventTime, UserID, SubAddr
from t
where prev_subaddr is null or prev_subaddr <> subaddr;

编辑:

如果您没有lag(),则可以使用apply

with t as (
      select t.*, tprev.subaddr as prev_subaddr
      from tablename t outer apply
           (select top (1) t2.*
            from tablename t2
            where t2.userid = t.userid and
                  t2.EventType = 20 and
                  t2.SubAddr in (1, 2) and
                  t2.eventtime < t.eventtime
            order by eventtime desc
           ) tprev
      where EventType = 20 and SubAddr in (1, 2)
    )
select EventTime, UserID, SubAddr
from t
where prev_subaddr is null or prev_subaddr <> subaddr;