TSQL没有提取完整的数据集

时间:2017-08-28 16:07:31

标签: sql sql-server tsql

我有一个复杂的存储过程很有效,直到客户想要更改它 复杂的TSQL我不是很好,所以我不知道我的代码有什么问题。

情况如下。我有三个临时表,费用,调整和付款。 最后,我将所有这些表合并在一个报表中。我遇到的问题是,即使这些表中的一个或甚至两个为空,只要一个表有数据我需要显示的数据。我目前已经设置了完整的外连接,但我仍然没有得到完整的列表,我可能会丢失......应该有50个记录。

任何人都可以看看这段代码并告诉我,我做错了什么?我将所有数据汇集在#ThisReportAll

UPDATE:所以我删除了having子句以查看发生了什么,并且逾期余额的数据返回null。所以数学是不正确的,任何想法?

CODE

 CREATE TABLE #BalanceAdjustmentsAll (CustomerId int, Amount decimal(20,2));
 CREATE TABLE #AnimalCostsAll (thisIndex int IDENTITY(1,1), AnimalTypeId int, Cost decimal(20,2));
 CREATE TABLE #TotalAnimalCostAll (thisIndex int IDENTITY(1,1), YearSetupId int, AnimalTypeId int, AnimalType varchar(max), OwnerId int, CustomerId int, AnimalCount int, TtlSpeciesCost decimal(20,2));
 CREATE TABLE #CustomerPaymentsAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), TtlPayments decimal(20,2));
 CREATE TABLE #CustomerInfoAll (thisIndex int IDENTITY(1,1), OwnerId int, CustomerId int, FName nvarchar(200), LName nvarchar(200),BName nvarchar(200));
 CREATE TABLE #ThisReportAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), Year char(4), OverdueBalance decimal(20,2), YearSetupId int);

 INSERT INTO #BalanceAdjustmentsAll (CustomerId, Amount)
 SELECT CustomerId, SUM(Amount)
 FROM BalanceAdjustment
 WHERE YearSetupId = 3
 GROUP BY CustomerId;

 /* GET Costs per Animal for 'This' yearID */
 INSERT INTO #AnimalCostsAll (AnimalTypeId, Cost)
 SELECT AnimalTypeId, Cost
 FROM PerCapitaFee
 WHERE YearSetupId = 3;

 /* GET animal type totals for owner per year */
 INSERT INTO #TotalAnimalCostAll (yearSetupId,AnimalTypeId,AnimalType,OwnerId,CustomerId,AnimalCount,TtlSpeciesCost)
 SELECT YearSetup.YearSetupId,AnimalCount.AnimalTypeId,AnimalType.ShortDescription,Owner.OwnerId,Report.CustomerId,AnimalCount.Count,(ac.Cost * AnimalCount.Count)
 FROM AnimalCount
 INNER JOIN #AnimalCostsAll as ac
 ON ac.AnimalTypeId = AnimalCount.AnimalTypeId
 INNER JOIN AnimalType
 ON AnimalCount.AnimalTypeId=AnimalType.AnimalTypeId
 INNER JOIN AnimalLocation
 ON AnimalLocation.AnimalLocationid=AnimalCount.AnimalLocationId
 INNER JOIN Owner
 ON Owner.OwnerId=AnimalLocation.OwnerId
 AND Owner.OwnerType = 'P'
 INNER JOIN Report
 ON Report.ReportId=Owner.ReportId
 INNER JOIN YearSetup
 ON Report.YearSetupId=YearSetup.YearSetupId
 INNER JOIN County
 ON County.CountyId=AnimalLocation.CountyId
 WHERE YearSetup.YearSetupId = 3 AND Report.Completed IS NOT NULL AND Report.CustomerId IS NOT NULL

 /* Get The total payments a customer has made */
 INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
 SELECT BPS.CustomerId,SUM(BPS.Amount)
 FROM BatchPaymentSplit BPS
 LEFT JOIN BatchPayment bp ON BPS.BatchPaymentId=bp.BatchPaymentId
 LEFT JOIN Batch b ON bp.BatchId=b.BatchId
 WHERE BPS.CustomerId IS NOT NULL
 AND
 (
 ((b.BatchTypeId = 'M' OR b.BatchTypeId = 'C' OR b.BatchTypeId = 'E') AND (b.BatchStatusId = 'S'))
 OR
 ((b.BatchTypeId = 'B' OR b.BatchTypeId = 'N' OR b.BatchTypeId = 'R' OR b.BatchTypeId = 'T') AND (b.BatchStatusId = 'S' OR b.BatchStatusId='C'))
 )
 AND
 BPS.YearSetupId = 3
 GROUP BY BPS.CustomerId;

 /* Deal with the name/id stuff */
 INSERT INTO #CustomerInfoAll(FName, LName, BName, OwnerId, CustomerId)
 SELECT
 o.FirstName AS FName,
 o.LastName AS LName,
 o.BusinessName AS BName,
 o.OwnerId AS OwnerId,
 r.CustomerId AS CustomerId
 FROM Owner o
 INNER JOIN Report r
 ON o.ReportId = r.ReportId
 AND o.OwnerType = 'P'
 WHERE r.CustomerId IN (SELECT CustomerId FROM #TotalAnimalCostAll)
 AND r.Completed IS NOT NULL
 AND r.YearSetupId = 3
 AND NOT EXISTS(
 SELECT 1 FROM Report
 WHERE r.CustomerId = Report.CustomerId
 AND Report.Completed IS NOT NULL
 AND r.ReportId != Report.ReportId
 AND r.YearSetupId = Report.YearSetupId
 AND (
 r.Completed < Report.Completed
 OR (
 r.Completed = Report.Completed
 AND r.ReportId < Report.ReportId
 )
 )
 )
 ORDER BY CustomerId;

 /**  MAKE IT SO #1  **************************************************/
 /* Simply Joining The Customer Info to the calculated totals to avoid any aggregation shenanigans... */
 INSERT INTO #ThisReportAll (CustomerID,Year,OverdueBalance,YearSetupId)
 SELECT COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID), ys.Name AS Year, 
 CASE 
    WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
        THEN (5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0) 
         ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0) 
 END
 AS TtlOwnerCost, t.YearSetupId AS YearSetupId
 FROM #TotalAnimalCostAll t
 FULL OUTER JOIN #CustomerPaymentsAll cp ON t.CustomerId=cp.CustomerID
 FULL OUTER JOIN #BalanceAdjustmentsAll ba ON COALESCE(t.CustomerId,cp.CustomerId)=ba.CustomerID
LEFT JOIN YearSetup ys ON COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID) = ys.YearSetupId     

GROUP BY COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID),ys.Name,cp.TtlPayments, ba.Amount, t.YearSetupId
 HAVING 
    CASE WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
        THEN SUM(5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
         ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
     END < 0;

 /*  Return some meaningful report data */
 SELECT r.Year AS [YearName],r.CustomerID,left(ci.FName,20) AS [FirstName], left(ci.LName,40) AS [LastName], left(ci.BName,40) AS [BusinessName],r.OverdueBalance AS [Balance],r.YearSetupId
 FROM #ThisReportAll r
 LEFT JOIN #CustomerInfoAll ci ON r.CustomerID = ci.CustomerId
 ORDER BY CAST(r.CustomerID as int) ASC;

 DROP TABLE #BalanceAdjustmentsAll;
 DROP TABLE #AnimalCostsAll;
 DROP TABLE #TotalAnimalCostAll;
 DROP TABLE #CustomerPaymentsAll;
 DROP TABLE #CustomerInfoAll;
 DROP TABLE #ThisReportAll;

2 个答案:

答案 0 :(得分:1)

找到它。如果t.TtlSpeciesCost为null,我没有默认值

SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)

SUM(ISNULL(t.TtlSpeciesCost,0)) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)

答案 1 :(得分:0)

可在此处找到一些缺失的记录: 通过调整/ *获取客户已支付的总金额* /

INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
 SELECT BPS.CustomerId,SUM(BPS.Amount)
 FROM BatchPaymentSplit BPS
 LEFT JOIN BatchPayment bp 
        ON BPS.BatchPaymentId=bp.BatchPaymentId
 LEFT JOIN Batch b 
        ON bp.BatchId=b.BatchId
       AND ((b.BatchTypeId IN ('M', 'C', 'E')   AND b.BatchStatusId = 'S')
        OR  (b.BatchTypeId IN ('B','N','R','T') AND (b.BatchStatusId IN ('S','C')))
 WHERE BPS.CustomerId IS NOT NULL
   AND BPS.YearSetupId = 3
 GROUP BY BPS.CustomerId;

B上的WHERE会否定左连接,导致省略空记录。或使左连接表现得像内连接。

要确定我们需要您的表中的样本数据,以显示您需要保留哪些记录。

我还重构了OR,并使它们成为“IN”以提高可读性。