我有一张表Customers
,其中包含PK CustomerID
和两个日期字段TransDate
和UpdatedDate
。
我有另一张表PaymentPlan
,其中有三个日期字段:StartDate
,EndDate
和UpdatedDate
。
我需要找到符合以下条件的所有Customer
条记录,然后将它们插入另一个表格。
TransDate
不是null
,属于任何一个PaymentPlan
记录的StartDate
和EndDate
。
TransDate
null
且UpdatedOn
介于任何一个PaymentPlan
记录的StartDate
和EndDate
之间。
无论TransDate
是否为null
,UpdatedOn
的{{1}}值必须早于Customers
UpdatedOn
}}
我遇到的问题是我的查询返回了重复的PaymentPlan
值。
这是我的程序:
CustomerID
如果我运行上述程序,则运行以下命令:
CREATE PROCEDURE USP_Find_Customers_For_ReCalc
@aDaysBack int
AS
BEGIN
SET NOCOUNT ON;
SET @aDaysBack = @aDaysBack * -1; -- Since we're looking "back" in time, we want the negative value of the number passed to the procedure
INSERT INTO ReCalc (CustomerID, InsertedOn, RecordStatus, ProcessedOn)
SELECT CustomerID, GETDATE() As InsertedOn, 0 As RecordStatus, null As ProcessedOn
FROM Customers
INNER JOIN
(SELECT P.Code, P.StartDate, P.EndDate, P.UpdatedOn
FROM PaymentPlan P
WHERE P.UpdatedOn >= DATEADD(day, @aDaysBack, GETDATE()) AND DeletedOn IS NULL
GROUP BY P.Code, P.StartDate, P.EndDate, P.UpdatedOn) PInfo ON Customers.Code = PInfo.Code
WHERE
(ISNULL(Customers.TransDate, Customers.UpdatedOn) >= PInfo.StartDate AND ISNULL(Customers.TransDate, Customers.UpdatedOn) <= PInfo.EndDate AND Customers.UpdatedOn < PInfo.UpdatedOn)
AND Customers.DeletedOn IS NULL
END
第二个结果大约是第一个结果的两倍。
我无法确定我的查询有什么问题导致在不需要实际重新计算时添加了太多重复客户。
答案 0 :(得分:2)
重复项是由PaymentPlan
表中的数据引起的。虽然意图是该表中定义的时段对于给定的Code
是非重叠的,但情况可能并非如此,并且可以解释重复项。
要确定PaymentPlan
表中是否确实存在此类重叠句点,请发出以下声明:
select p1.code, p1.StartDate
from PaymentPlan p1
inner join PaymentPlan p2
on p1.code = p2.code
and p1.StartDate between p2.StartDate and p2.EndDate
如果此查询返回记录,则说明重复项。返回的记录将为您提供在PaymentPlan
表中查找此类不一致的位置的线索。
解决了这些后,您将不再生成重复项。
答案 1 :(得分:0)
尝试在内部查询中链接回Customers
:
SET NOCOUNT ON;
SET @aDaysBack = @aDaysBack * -1; -- Since we're looking "back" in time, we want the negative value of the number passed to the procedure
INSERT INTO ReCalc (CustomerID, InsertedOn, RecordStatus, ProcessedOn)
SELECT CustomerID, GETDATE(), 0, null
FROM Customers
INNER JOIN
(
SELECT P.Code, P.StartDate, P.EndDate
FROM PaymentPlan P
INNER JOIN
Customers c2 ON c2.Code = p.Code
AND c2.UpdatedOn < p.UpdatedOn
AND c2.DeletedOn IS NULL
WHERE P.UpdatedOn >= DATEADD(day, @aDaysBack, GETDATE())
AND P.DeletedOn IS NULL
GROUP BY P.Code, P.StartDate, P.EndDate
)
PInfo
ON Customers.Code = PInfo.Code
AND ISNULL(Customers.TransDate, Customers.UpdatedOn)
BETWEEN PInfo.StartDate AND PInfo.EndDate