“如果查询返回B中不存在A,但是如果存在A仅返回A”的SQL语法

时间:2019-05-10 13:57:56

标签: sql tsql sql-server-2012

我有一个查询,该查询从GLTable返回当前和将来的收入。我需要返回两种发布类型。如果Postingtype A不存在,则返回Postingtype B,如果Postingtype A仅存在,则返回postingtypeA。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 :(得分:0)

这是你的意思吗?

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
		)