Два CTE и UNION ALL для сравнения наборов данных дают неожиданные результаты - PullRequest
0 голосов
/ 25 мая 2018

Два CTE были написаны для возврата наборов результатов из различных операторов выбора.СОЮЗ ВСЕ из наборов результатов заканчиваются количеством различий между двумя cte, меняющимися каждый раз, когда он выполняется.

Я закомментировал некоторые строки скрипта, и похоже, что проблема связана с UNION ALL из наборов результатов для столбцов «Premium», «Taxes», «TimeSpanID».Есть ли другой метод, который можно использовать для сравнения результатов скрипта ниже:

WITH
CTE1 AS (
select [TransactionDateID]
  ,[TransactionTypeID]
  ,[TransactionID]
  ,[BillingAccountID]
  ,[BillingInvoiceID]
  ,[BillingPaymentID]
  ,[Premium]
  ,[Taxes]
  ,[TimeSpanID]
  from Fact.SalesBalance1
) ,
CTE2 AS(
SELECT TransactionDateID=MAX(TransactionDateID) OVER (PARTITION BY 
[BillingAccountID] ORDER BY [StartDate]),
TransactionTypeID,
TransactionID,
BillingAccountID,
BillingInvoiceID,
BillingPaymentID,
Premium=SUM(Premium) OVER (PARTITION BY [BillingAccountID] ORDER BY 
StartDate),
Taxes=SUM(Taxes) OVER (PARTITION BY [BillingAccountID] ORDER BY StartDate),
TimeSpanID
FROM 
(
    SELECT *,

    StartDate=[DateKey],

    EndDate=ISNULL(MAX([DateKey]) OVER (PARTITION BY [BillingAccountID] 
ORDER BY DateKey ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING),
CAST('12/31/9999' AS DATE))
    FROM Fact.SalesTransaction P
    INNER JOIN Dim.SalesTransDate Q ON P.TransactionDateID = 
Q.CalendarDateID
) T
CROSS APPLY (
    SELECT TimeSpanID FROM Dim.TimeSpan WHERE StartDate = T.StartDate AND 
EndDate = T.EndDate
)TS  

)

SELECT MIN(TableName) as TableName
, TransactionDateID
,TransactionTypeID
,TransactionID
,BillingAccountID
,BillingInvoiceID
,BillingPaymentID
,Premium
,Taxes
,TimeSpanID
FROM
(
SELECT 'Fact CTE1' as TableName
, A.TransactionDateID
,A.TransactionTypeID
,A.TransactionID
,A.BillingAccountID
,A.BillingInvoiceID
,A.BillingPaymentID
,A.Premium
,A.Taxes
,A.TimeSpanID
FROM CTE1 A
UNION ALL
SELECT 'Fact CTE2’ as TableName, B.TransactionDateID
,B.TransactionTypeID
,B.TransactionID
,B.BillingAccountID
,B.BillingInvoiceID
,B.BillingPaymentID
,B.Premium
,B.Taxes
,B.TimeSpanID
FROM CTE2 B
) tmp

GROUP BY TransactionDateID
,TransactionTypeID
,TransactionID
,BillingAccountID
,BillingInvoiceID
,BillingPaymentID
,Premium
,Taxes
,TimeSpanID
HAVING COUNT(0) = 1
ORDER BY TransactionDateID
,TransactionTypeID
,TransactionID
,BillingAccountID
,BillingInvoiceID
,BillingPaymentID
,TimeSpanID

1 Ответ

0 голосов
/ 25 мая 2018

Похоже, что UNION ALL не очень хорошо играет в моем вопросе.Я изменил «UNION ALL» на «INTERSECT» в соответствии с обновленным сценарием ниже, и он работал:

WITH
CTE1 AS (
select [TransactionDateID]
  ,[TransactionTypeID]
  ,[TransactionID]
  ,[BillingAccountID]
  ,[BillingInvoiceID]
  ,[BillingPaymentID]
  ,[Premium]
  ,[Taxes]
  ,[TimeSpanID]
  from Fact.SalesBalance1
) ,
CTE2 AS(
SELECT TransactionDateID=MAX(TransactionDateID) OVER (PARTITION BY 
[BillingAccountID] ORDER BY [StartDate]),
TransactionTypeID,
TransactionID,
BillingAccountID,
BillingInvoiceID,
BillingPaymentID,
Premium=SUM(Premium) OVER (PARTITION BY [BillingAccountID] ORDER BY 
StartDate),
Taxes=SUM(Taxes) OVER (PARTITION BY [BillingAccountID] ORDER BY StartDate),
TimeSpanID
FROM 

(
    SELECT *,

    StartDate=[DateKey],

    EndDate=ISNULL(MAX([DateKey]) OVER (PARTITION BY [BillingAccountID] 
ORDER BY DateKey ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING),
CAST('12/31/9999' AS DATE))
    FROM Fact.SalesTransaction P
    INNER JOIN Dim.SalesTransDate Q ON P.TransactionDateID = 
Q.CalendarDateID
) T
CROSS APPLY (
    SELECT TimeSpanID FROM Dim.TimeSpan WHERE StartDate = T.StartDate AND 
EndDate = T.EndDate
)TS  

)

SELECT MIN(TableName) as TableName
, TransactionDateID
,TransactionTypeID
,TransactionID
,BillingAccountID
,BillingInvoiceID
,BillingPaymentID
,Premium
,Taxes
,TimeSpanID
FROM

(
SELECT 'Fact CTE1' as TableName
, A.TransactionDateID
,A.TransactionTypeID
,A.TransactionID
,A.BillingAccountID
,A.BillingInvoiceID
,A.BillingPaymentID
,A.Premium
,A.Taxes
,A.TimeSpanID
FROM CTE1 A
INTERSECT
--UNION ALL
SELECT 'Fact CTE2’ as TableName, B.TransactionDateID
,B.TransactionTypeID
,B.TransactionID
,B.BillingAccountID
,B.BillingInvoiceID
,B.BillingPaymentID
,B.Premium
,B.Taxes
,B.TimeSpanID

ОТ CTE2 B) tmp

GROUP BY TransactionDateID, TransactionTypeID, TransactionID, BillingAccountID, BillingInvoiceID, BillingPaymentID, Премиум, Налоги, TimeSpanID, COUNT COUNT (0) = 1 ORDER BY TransactionDateID, TransactionTypeID, TransactionID, BillingAccountID, BillingInvoiceID, BillingPaymentID, TimeSpanID

...