不确定此查询为何插入重复记录

时间:2016-08-23 18:31:11

标签: sql sql-server

我有一张表Customers,其中包含PK CustomerID和两个日期字段TransDateUpdatedDate

我有另一张表PaymentPlan,其中有三个日期字段:StartDateEndDateUpdatedDate

我需要找到符合以下条件的所有Customer条记录,然后将它们插入另一个表格。

  • TransDate不是null,属于任何一个PaymentPlan记录的StartDateEndDate

  • TransDate nullUpdatedOn介于任何一个PaymentPlan记录的StartDateEndDate之间。

    < / LI>
  • 无论TransDate是否为nullUpdatedOn的{​​{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

第二个结果大约是第一个结果的两倍。

我无法确定我的查询有什么问题导致在不需要实际重新计算时添加了太多重复客户。

2 个答案:

答案 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