我有一个场景,我需要使用SQL在Table中查找缺少的记录 - 不使用Cursor,Views,SP。
以下数据将更好地解释它。
CustID Start_Date End_Date
1 19000101 20121231
1 20130101 20130831
1 20130901 20140321
1 20140321 99991231
基本上我试图在SCD2场景中填充数据。
现在我想找到丢失的记录(或CustID)。
如下所示,我们没有CustID = 4
与Start_Date = 20120606
和End_Date = 20140101
CustID Start_Date End_Date
4 19000101 20120605
4 20140102 99991231
创建表的代码
CREATE TABLE TestTable
(
CustID int,
Start_Date int,
End_Date int
)
INSERT INTO TestTable values (1,19000101,20121231)
INSERT INTO TestTable values (1,20130101,20130831)
INSERT INTO TestTable values (1,20130901,20140321)
INSERT INTO TestTable values (1,20140321,99991231)
INSERT INTO TestTable values (2,19000101,99991213)
INSERT INTO TestTable values (3,19000101,20140202)
INSERT INTO TestTable values (3,20140203,99991231)
INSERT INTO TestTable values (4,19000101,20120605)
--INSERT INTO TestTable values (4,20120606,20140101) --Missing Value
INSERT INTO TestTable values (4,20140102,99991231)
现在SQL应该返回CustID = 4
,因为它缺少值。
答案 0 :(得分:2)
我的想法是基于这种逻辑。让我们假设19000101为1,99991231为10.现在对于所有ID,如果减去End_date - start_date并将它们相加,则总和必须等于9(10 - 1)。你可以在这里做同样的事情
SELECT ID, SUM(END_DATE - START_DATE) as total from TABLE group by ID where total < (MAX_END_DATE - MIN_START_DATE)
您可能希望在SQL中找到命令,该命令提供2天之间的天数,并在SUM部分中使用该命令。
让我们采取以下示例
1 1900 2003
1 2003 9999
2 1900 2222
2 2222 9977
3 1900 9999
查询将按如下方式执行
1 (2003 - 1900) + (9999 - 2003) = 1 8098
2 (2222 - 1900) + (9977 - 2222) = 2 9077
3 (9999 - 1900) = 3 8098
where子句将消除1和3,只给你2,这就是你想要的。
答案 1 :(得分:0)
如果您只需要CustID,那么这将完成
SELECT t1.CustID
FROM TestTable t1
LEFT JOIN TestTable t2
ON DATEADD(D, 1, t1.Start_Date) = t2.Start_Date
WHERE t2.CustID IS NULL
GROUP BY t1.CustID
答案 2 :(得分:0)
如果满足以下条件之一,则需要行:
您可以将联接保留到同一个表中以查找上一行和下一行,并通过检查列值为null来过滤未找到行的结果:
SELECT t1.CustID, t1.StartDate, t1.EndDate
FROM TestTable t1
LEFT JOIN TestTable tPrevious on tPrevious.CustID = t1.CustID
and tPrevious.EndDate = t1.StartDate - 1
LEFT JOIN TestTable tNext on tNext.CustID = t1.CustID
and tNext.StartDate = t1.EndDate + 1
WHERE (t1.EndDate <> 99991231 and tNext.CustID is null) -- no following
or (t1.StartDate <> 19000101 and tPrevious.CustID is null) -- no previous