Синтаксис SQL для «Если A не существует в Query Return B, но если A существует, только вернуть A» - PullRequest
1 голос
/ 10 мая 2019

У меня есть запрос, который возвращает текущий и будущий доход от GLTable. Есть два типа публикации, которые мне нужно вернуть. Если Postingtype A не существует, верните Postingtype B, если Postingtype A существует, только верните Postingtype A. DB - MSSQL 2014.

Я пробовал несколько вариантов ниже,

WHERE (EXISTS (SELECT 1 FROM GLAccountPosting WHERE PostingType = 10) 
        )
        OR
        NOT EXISTS (SELECT 1 FROM GLAccountPosting WHERE PostingType = 14) 

        (;

WHERE 
postingtype in (14, 10)
AND
    (StartDateTime > '2019/07/01' AND postingtype = 10)
    OR
     (StartDateTime < '2019/07/01' AND postingtype = 14);

WHERE
    (StartDateTime > '2019/07/01' AND postingtype = 10 ) OR
    (StartDateTime < '2019/07/01' OR postingtype = 14);

Запрос ниже (усечен, поскольку он очень большой):

SELECT 

prepay.Prepay,
Case When GAP.postingtype = 14 then isnull(sum(GAP.CreditValue),0) ELSE 0 end as CreditTodate,
Case When GAP.postingtype = 14 then prepay.Prepay -  isnull(sum(GAP.CreditValue),0) ELSE prepay.Prepay   end AS Balance,

GAP.PostingType


 FROM
GLAccountPosting AS GAP

    JOIN (SELECT 

                        SalesTransactions.BranchID,
                        Departments.DepartmentGUID,
                        SalesTransactions.SalesTransactionGUID,
                        SalesTransactionDetails.SalesTransactionLineGUID,
                        Sum(SalesTransactionDetails.Prepayvalue) AS Prepay



                 FROM   
                      intellimanager.dbo.SalesTransactionDetails
                      INNER JOIN  intellimanager.dbo.SalesTransactions ON SalesTransactionDetails.SalesTransactionGUID=SalesTransactions.SalesTransactionGUID
                      INNER JOIN  intellimanager.dbo.SalesTransactionLines ON SalesTransactionDetails.SalesTransactionLineGUID=SalesTransactionLines.SalesTransactionLineGUID
                      INNER JOIN  intellimanager.dbo.Departments on Departments.DepartmentGUID = SalesTransactionDetails.ItemDepartmentGUID
                      left  JOIN  intellimanager.dbo.BookingLinesDetails on BookingLinesDetails.BookinglinesDetailGUID = SalesTransactionDetails.BookinglinesDetailGUID
                      LEFT JOIN  intellimanager.dbo.BookingLines on BookingLines.BookingLineGUID = BookingLinesDetails.BookingLineGUID

                 WHERE  
                      (
                            SalesTransactionDetails.AccrualStatus = 1 OR SalesTransactionDetails.AccrualStatus=2 -- 1 = reversed, 2 = deferred
                      ) AND
                        SalesTransactions.PostingDateTime < DateAdd(day,1,'2019/04/27') and
                        SalesTransactionDetails.BranchID IN (SELECT number FROM dbo.InzSplitInt(1)) AND-- selected branch 
                        SalesTransactionDetails.AccrualType = 2 AND  --- sessions only
                        SalesTransactionDetails.PrepayValue <> 0 AND
                        isnull(SalesTransactionLines.CreditSalesTransactionLineGUID,0x0) = 0x0  and -- remove credited lines      
                        SalesTransactions.status = 1 and -- remove not finalised and cancelled invoices
                        BookingLinesDetails.ItemType = 1 and  
                      (BookingLinesDetails.BookingDetailProgress not in (2,4) or 
                        (
                            BookingLinesDetails.BookingDetailProgress in (2,4) and SalesTransactionDetails.AccrualStatus <> 1)
                        ) 
                        and
                        (   
                            BookingLinesDetails.CalendarLinkGUID is null or 
                            (BookingLinesDetails.CalendarLinkGUID is not null and BookingLinesDetails.StartDateTime >= '2019/01/01'
                            )
                        ) 

                         -- include all sales tran details that are for bookings in the future
                         -- whether they have been completed or not and whether they have 

                        GROUP BY 
                            SalesTransactions.BranchID,
                            SalesTransactions.SalesTransactionGUID,
                            SalesTransactionDetails.SalesTransactionLineGUID,
                            Departments.DepartmentGUID,
                            BookingLinesDetails.StartDateTime) As prepay on prepay.SalesTransactionLineGUID = GAP.SalesTransactionLineGUID
                        JOIN salestransactionlines stl on stl.salestransactionlineguid = gap.salestransactionlineguid

                        LEFT JOIN salestransactiondetails sd on sd.SalesTransactiondetailGUID = GAP.SalesTransactiondetailGUID


where 
        GAP.ItemType = 1



group by


GAP.GLPostingDescription,
GAP.postingtype,
GAP.FormattedGLAccountCode,
prepay.Prepay,
GAP.PostingType

Мне нужны следующие результаты:

Prepaid   Current Future  postingtype
26.90     0.00    26.90   10
215.20  215.20     0.00   14

В каждой строке может быть как Postingtype 10, так и 14, но я хочу видеть только одну за раз. Если оба показываются для одной и той же транзакции, это делает итоговые неточные.

1 Ответ

0 голосов
/ 14 мая 2019

Это то, что вы имеете в виду?

DECLARE @t TABLE (TransactionID INT)
DECLARE @p TABLE (PostingType CHAR(1), TransactionID INT)

INSERT INTO @t
(TransactionID)
VALUES
(1),
(2),
(3)

INSERT INTO @p
(PostingType, TransactionID)
VALUES
('A', 1),
('B', 1),
('A', 2),
('B', 3)

SELECT t.TransactionID FROM @t t
WHERE
	EXISTS
		(
			SELECT 1 FROM @p p
			PIVOT  
			(  
			COUNT(p.PostingType)  
			FOR p.PostingType IN ([A], [B])  
			) sq
			WHERE
				(
					([A] = 0 AND [B] > 0) --Postingtype A does not exist then return postingtype B
					OR ([A] > 0 AND [B] = 0) --If postingtype A exists only return postingtype A
				)
				AND sq.TransactionID = t.TransactionID
		)
...