Ne savez pas pourquoi cette requête insère des loggings en double

J'ai une table Customers qui a le PK CustomerID et deux champs de date TransDate et UpdatedDate .

J'ai une autre table PaymentPlan qui a trois champs de date: StartDate , UpdatedDate et UpdatedDate .

J'ai besoin de find tous les loggings du Customer qui répondent aux critères suivants, puis les insert dans une autre table.

Le problème que je rencontre est que ma requête renvoie des valeurs CustomerID double.

C'est ma procédure:

 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 

Si j'exécute la procédure ci-dessus, exécutez les commands suivantes:

 SELECT COUNT(DISTINCT(CustomerID)) FROM ReCalc SELECT COUNT(CustomerID)) FROM ReCalc 

Le deuxième résultat est approximativement deux fois plus grand que le premier résultat.

Je ne peux pas déterminer ce qui ne va pas dans ma requête, ce qui entraîne l'ajout de nombreux clients en double lorsqu'ils n'ont pas besoin d'être recalculés.

Les duplicates sont provoqués par datatables de la table PaymentPlan . Bien que l'intention soit que les périodes définies dans ce tableau ne se chevauchent pas pour un Code donné, ce n'est probablement pas le cas, et cela expliquerait les duplicates.

Pour identifier si vous avez effectivement des périodes qui se chevauchent dans la table PaymentPlan , émettez cette instruction:

 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 

Si cette requête renvoie des loggings, cela explique les duplicates. Les loggings returnnés vous donneront une idée de l'location de ces incohérences dans la table PaymentPlan .

Une fois que vous avez résolu ceux-ci, vous ne produirez plus de duplicates.

Essayez de renvoyer vers les Customers dans la requête interne:

 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