SQL查找缺失记录

时间:2014-07-21 15:00:29

标签: sql sql-server tsql

我有一个场景,我必须找到丢失的记录。

--Code for Creating Source Table
CREATE TABLE [dbo].[NaTarget](
    [BillKey] [int] NULL,
    [StartDate] [date] NULL,
    [EndDate] [date] NULL
) 
GO

--Code for Creating Target Table
CREATE TABLE [dbo].[NaSource](
    [BillKey] [int] NULL,
    [StartDate] [date] NULL,
    [EndDate] [date] NULL
) 
GO

--Inserting Records in Source
INSERT INTO [dbo].[NaSource]  ([BillKey],[StartDate],[EndDate])
     VALUES('1','2014-01-13','2014-03-27')
GO

INSERT INTO [dbo].[NaSource]([BillKey],[StartDate],[EndDate])
     VALUES('2','2014-02-14','2014-04-20')
GO

INSERT INTO [dbo].[NaSource]([BillKey],[StartDate],[EndDate])
     VALUES('3','2013-11-13','2014-01-18')
GO

--Inserting records In Target
INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('1','2014-01-13' , '2014-01-31' )        

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('1','2014-02-01' , '2014-02-28'     )     

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('1','2014-03-01' , '2014-03-27'     )     

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('2','2014-02-14' , '2014-02-28'     )     

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('2','2014-03-01' , '2014-03-31'     )     

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('2','2014-04-01' , '2014-04-20'     )     

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('3','2013-11-13' , '2013-11-30'     )    

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('3','2013-12-01' , '2013-12-31'     )    

INSERT INTO [dbo].[NaTarget] ([BillKey] ,[StartDate],[EndDate]) 
VALUES ('3','2014-01-01' , '2014-01-18'     )    

现在,对于任何BillKey,目标中的StartDate将是来自Source的StartDate,而EndDate将是月份的最后日期,现在是同一Billkey,下一个记录将具有下个月的第一个日期,EndDate将是最后一个日期,直到达到相同BillKey的最后一个日期。

我必须找到任何记录,如果它被删除。

BillKey = 3

的示例
StartDate= 2013-12-01   EndDate = 2013-12-31 is 

目标中没有我们需要找到它

示例将更好地解释

4 个答案:

答案 0 :(得分:2)

以下是对此的尝试:如果我正确理解您的问题,您需要检查以查看源表中基于开始日期和结束日期的目标表格中的任何预期值是否为'实际上在那里。

您需要基本上使用NaSource表格StartDateEndDate中的内容重新创建结果表格,然后针对{ {1}}表。

我很肯定这是一种更有效的方式(最好不使用游标和循环),但这应该会给你你想要的结果:

NaTarget

答案 1 :(得分:2)

这是我使用递归CTE的解决方案。构建natarget表应该是什么样子并将其与实际natarget进行比较。我开始对日期片段感到困惑,因此它可能会被简化,但这确实有效。

;with targetCte
as
(
 select  billkey, 
   startdate, 
   CAST(DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, startdate) + 1, 0)) as DATE) as enddate
 from nasource
 union all
 select t.billkey, 
   cast(DATEADD(month, DATEDIFF(mm, 0, dateadd(mm, 1, t.startdate)), 0) as DATE) , 
   case
     when cast(DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, DATEADD(month, DATEDIFF(mm, 0, dateadd(mm, 1, t.startdate)), 0)) + 1, 0)) as DATE) < n.enddate then cast(DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, DATEADD(month, DATEDIFF(mm, 0, dateadd(mm, 1, t.startdate)), 0)) + 1, 0)) as DATE)
     else n.enddate
   end
      as enddate 
 from targetCte t
 join nasource n on n.billkey = t.billkey 
 where t.enddate < n.enddate
)


select * from targetcte t
where not exists
  (select * 
   from natarget nt 
   where t.billkey = nt.billkey
   and t.startdate = nt.startdate
   and t.enddate = nt.enddate)

答案 2 :(得分:0)

将所有记录插入一个具有唯一ID的表(调用此主表)

获取已删除记录的表,然后在主表上运行SELECT *,其中已删除记录表的ID NOT IN ID列

答案 3 :(得分:0)

通过对帐进行过滤。 LEFT在StartDate和EndDate对上加入两个表WHERE RIGHT键为NULL。谷歌SQL连接,你可以找到一个非常有用的图表来解决这个问题。