【问题标题】:Finding duplicate records in a specific date range查找特定日期范围内的重复记录
【发布时间】:2017-12-02 20:23:34
【问题描述】:

我有一张有 4 列的表格 Serial(nvarchar)、SID(nvarchar)、DateCreated(Date)、CID(unique and int) 我想找到有重复 serialSID 以及 2 个重复 serial 位于 180 天日期范围之间的记录。 p>

请帮忙

样本数据

Serial          SID     DateCreated             CID 
02302-25-0036   HONMD01 2017-05-01 00:00:00.000 1
02302-25-0036   HONMD01 2017-05-01 00:00:00.000 3
0264607         HONMD01 2017-05-01 00:00:00.000 65
0264607         HONMD01 2016-05-01 00:00:00.000 45
03118-09-0366   PRIVA00 2016-05-20 00:00:00.000 34
03118-09-0366   PRIVA00 2016-05-20 00:00:00.000 87
0969130         140439  2017-05-09 00:00:00.000 32
0969130         140439  2017-05-09 00:00:00.000 23
1049567         INIIL00 2017-04-12 00:00:00.000 76

【问题讨论】:

  • 请提供一些示例数据和预期输出
  • 您想了解当前行是否在过去 180 天内?
  • 添加了示例数据。例如,对于序列 02302-25-0036,有两个具有相同 SID 的条目,并且都在 180 天内,我们想要该数据。如果两个日期相差超过 180,我们不希望这样
  • 不要将样本数据添加为图像。很难复制粘贴

标签: sql sql-server sql-server-2008


【解决方案1】:
create table #Test (Serial nvarchar(20), [SID] nvarchar(10), DateCreated datetime, CID int)

Insert into #Test   values ('02302-25-0036', 'HONMD01', '2017-05-01 00:00:00.000', 1)
                    , ('02302-25-0036', 'HONMD01', '2017-05-01 00:00:00.000', 3)
                    , ('0264607', 'HONMD01', '2017-05-01 00:00:00.000', 65)
                    , ('0264607', 'HONMD01', '2016-05-01 00:00:00.000', 45)
                    , ('03118-09-0366', 'PRIVA00', '2016-05-20 00:00:00.000', 34)
                    , ('03118-09-0366', 'PRIVA00', '2016-05-20 00:00:00.000', 87)
                    , ('0969130', '140439', '2017-05-09 00:00:00.000', 32)
                    , ('0969130', '140439', '2017-05-09 00:00:00.000', 23)
                    , ('1049567', 'INIIL00', '2017-04-12 00:00:00.000', 76)

select distinct a.* 
from
(
select t.*
from #Test t
inner join (
    Select Serial, [SID]
    from #Test
    group by Serial, [SID]
    Having count(*)>=2
    ) d on d.Serial = t.Serial and t.SID= t.SID
) a
full outer join
(
select t.*
from #Test t
inner join (
    Select Serial, [SID]
    from #Test
    group by Serial, [SID]
    Having count(*)>=2
    ) d on d.Serial = t.Serial and t.SID= t.SID
) b on a.Serial = b.Serial and a.SID= b.SID
where datediff(d,a.DateCreated, b.DateCreated)<180

【讨论】:

    【解决方案2】:

    尝试这样做:

    with cte as (
        select 
            serial,
            sid,
            dateCreated,
            cid,
            coalesce(max(dateCreated) over(partition by serial, sid order by cid, dateCreated asc rows between unbounded preceding and 1 preceding), '1900-01-01') as last,
            coalesce(min(dateCreated) over(partition by serial, sid order by cid, dateCreated asc rows between 1 following and unbounded following), '5999-01-01') as next
        from table_name
    ) 
    select *
    from cte 
    where 
        datediff(day, last, dateCreated) >= 180
        and datediff(day, dateCreated, next) >= 180
    

    【讨论】:

    • 谢谢Евгений Кондратенко
    【解决方案3】:

    这是一个具有挑战性的问题!为了便于理解,我将最终输出保留为 *(PreviousDate, rno)。这是我的解决方法:

    Create table #t(Serial nvarchar(100),SID nvarchar(100),DateCreated date,CID int)
    Insert into #t values 
    ('02302-25-0036',   'HONMD01', '2017-05-01 00:00:00.000', 1),
    ('02302-25-0036',   'HONMD01', '2017-05-01 00:00:00.000', 3),
    ('0264607',         'HONMD01', '2017-05-01 00:00:00.000', 65),
    ('0264607',         'HONMD01', '2016-05-01 00:00:00.000', 45),
    ('03118-09-0366',   'PRIVA00', '2016-05-20 00:00:00.000', 34),
    ('03118-09-0366',   'PRIVA00', '2016-05-20 00:00:00.000', 87),
    ('0969130',         '140439',  '2017-05-09 00:00:00.000', 32),
    ('0969130',         '140439',  '2017-05-09 00:00:00.000', 23),
    ('1049567',         'INIIL00', '2017-04-12 00:00:00.000', 76)
    
    Select iq2.*
    FROM
     (Select iq.Serial, iq.SID, iq.DateCreated, iq.CID, iq.PreviousDate,
             ROW_NUMBER() OVER (PARTITION BY iq.Serial,iq.SID, CASE WHEN DATEDIFF(day, iq.DateCreated, iq.PreviousDate) <= 180 THEN 1 ELSE 0 END 
                                ORDER BY Serial,SID) rno
      FROM
          (select Serial,SID,DateCreated,CID,
                  MAX(DateCreated) OVER (PARTITION BY Serial,SID ORDER BY Serial,SID) maxDate,
                  DATEADD(day,-180,MAX(DateCreated) OVER (PARTITION BY Serial,SID ORDER BY Serial,SID)) PreviousDate
           from #t
        )iq
     )iq2 
    where iq2.rno <> 1
    

    输出:

    Serial                    SID        DateCreated   CID         PreviousDate   rno
    ----------               -------     ----------   ----         -----------   ----
    02302-25-0036            HONMD01     2017-05-01    3           2016-11-02     2
    03118-09-0366            PRIVA00     2016-05-20    87          2015-11-22     2
    0969130                  140439      2017-05-09    23          2016-11-10     2
    

    PS : PreviousDate 是 MAX PreviousDate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-26
      • 2021-11-09
      • 1970-01-01
      • 2023-03-20
      • 2022-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多