有人能弄明白如何摆脱NOT EXISTS
条款中的WHERE
陈述吗?
SELECT TOP 100 PERCENT
Ftm.AcctID AS [Acct Id],
Act.AccountNumber AS [Account No.],
Act.AccountTypeId,
ISNULL(Cnt.FirstName, '')+ ' ' + ISNULL(Cnt.LastName, '') AS [Full Name],
Ftm.FinTransTypeCode AS [Trans Type],
Ftm.FinTransCode AS [Trans Code],
Fm.FJNo AS [FJ No.],
Fm.ReversalFJNo AS [Reversal FJNo.],
CAST(ISNULL(Fm.FJAmt,0) AS DECIMAL(9, 2)) AS Amount,
Ftc.InterfaceDescr AS [Transaction Desc],
Fm.Comments, Fm.CreatedBy AS [Posted By],
Ftm.Created,RegistrationTypeid, FJDate
FROM
FinMaster AS Fm
INNER JOIN FinTransMaster AS Ftm ON Ftm.FjNo = Fm.FJNo
INNER JOIN dbo.Account AS Act ON Ftm.AcctID = Act.AccountId
INNER JOIN dbo.Contact AS Cnt ON Act.PrimaryContactId = Cnt.ContactId
INNER JOIN FinTransCodes AS Ftc ON Ftc.FinTransCode = Ftm.FinTransCode
WHERE
(Ftm.FinTransTypeCode <> 'PYMT') AND FJDate > getdate()-5
AND (NOT EXISTS (SELECT '' AS Expr1
FROM FinMaster
WHERE (ReversalFjNo = Fm.FJNo)))
AND (NOT EXISTS (SELECT '' AS Expr1
FROM FinTransMaster AS Ftm2
WHERE (FjNo = Ftm.FjNo) AND (FjTransSeqNo < Ftm.FjTransSeqNo)))
ORDER BY Ftm.Created DESC
答案 0 :(得分:4)
在SQL Server中,NOT IN / NOT EXISTS 比LEFT JOIN更好 ,因为它的优化器无法在LEFT JOIN / IS NULL中识别ANTI JOIN。它将返回整个结果集,然后过滤掉NULL。
WITH contacts AS (
SELECT t.contactid,
CASE
WHEN t.firstname IS NULL AND t.lastname IS NULL THEN
''
WHEN t.firstname IS NULL THEN
t.lastname
WHEN t.lastname IS NULL THEN
t.firstname
ELSE
t.FirstName + ' ' t.LastName
END AS [fullname]
FROM dbo.CONTACT t)
SELECT TOP 100 PERCENT
ftm.AcctID AS [Acct Id],
a.AccountNumber AS [Account No.],
a.AccountTypeId,
c.fullname AS [Full Name],
ftm.FinTransTypeCode AS [Trans Type],
ftm.FinTransCode AS [Trans Code],
t.FJNo AS [FJ No.],
t.ReversalFJNo AS [Reversal FJNo.],
CAST(ISNULL(t.FJAmt, 0) AS DECIMAL(9, 2)) AS Amount,
ftc.InterfaceDescr AS [Transaction Desc],
t.Comments,
t.CreatedBy AS [Posted By],
ftm.Created,
RegistrationTypeid,
FJDate
FROM FINMASTER t
JOIN FINTRANSMASTER ftm ON ftm.FjNo = t.FJNo
AND ftm.FinTransTypeCode <> 'PYMT'
JOIN dbo.ACCOUNT a ON a.accountid = ftm.AcctID
JOIN contacts c ON c.contactid = a.PrimaryContactId
JOIN FINTRANSCODES ftc ON ftc.FinTransCode = ftm.FinTransCode
WHERE FJDate > getdate()-5
AND NOT EXISTS (SELECT NULL
FROM FinMaster fm
WHERE fm.ReversalFjNo = t.FJNo)
AND NOT EXISTS (SELECT NULL
FROM FinTransMaster AS ftm2
WHERE ftm2.FjNo = ftm.FjNo
AND ftm2.FjTransSeqNo < ftm.FjTransSeqNo)
ORDER BY ftm.Created DESC
答案 1 :(得分:2)
为什么要让自己接受这个?良好地使用子查询(特别是使用IN和NOT IN)使查询更具可读性,并且它们在大多数数据库引擎上都同样快。
通常,在要选择的表上使用JOIN,为其他所有内容使用子查询会导致最清晰的查询。这就是我的建议。
SELECT TOP 100 PERCENT
Ftm.AcctID AS [Acct Id],
Act.AccountNumber AS [Account No.],
Act.AccountTypeId,
ISNULL(Cnt.FirstName, '')+ ' ' + ISNULL(Cnt.LastName, '') AS [Full Name],
Ftm.FinTransTypeCode AS [Trans Type],
Ftm.FinTransCode AS [Trans Code],
Fm.FJNo AS [FJ No.],
Fm.ReversalFJNo AS [Reversal FJNo.],
CAST(ISNULL(Fm.FJAmt,0) AS DECIMAL(9, 2)) AS Amount,
Ftc.InterfaceDescr AS [Transaction Desc],
Fm.Comments, Fm.CreatedBy AS [Posted By],
Ftm.Created,RegistrationTypeid, FJDate
FROM
FinMaster AS Fm
INNER JOIN FinTransMaster AS Ftm ON Ftm.FjNo = Fm.FJNo
INNER JOIN dbo.Account AS Act ON Ftm.AcctID = Act.AccountId
INNER JOIN dbo.Contact AS Cnt ON Act.PrimaryContactId = Cnt.ContactId
INNER JOIN FinTransCodes AS Ftc ON Ftc.FinTransCode = Ftm.FinTransCode
WHERE
(Ftm.FinTransTypeCode <> 'PYMT') AND FJDate > getdate()-5
AND Fm.FJNo NOT IN (
SELECT ReversalFjNo
FROM FinMaster
WHERE ReversalFjNo IS NOT NULL)
AND Ftm.FjNo NOT IN (
SELECT FjNo
FROM FinTransMaster AS Ftm2
WHERE FjNo IS NOT NULL)
AND (FjTransSeqNo < Ftm.FjTransSeqNo)))
ORDER BY Ftm.Created DESC
答案 2 :(得分:0)
我认为您可以在FinMaster和FinTransMaster表上执行OUTER JOIN,并使where子句指定这些表中的ID为空。
答案 3 :(得分:0)
你只需要进行连接,其中null为空 以下是使用您提供的查询的示例:
选择前100%
Ftm.AcctID AS [Acct Id],
Act.AccountNumber AS [账号],
Act.AccountTypeId,
ISNULL(Cnt.FirstName,'')+''+ ISNULL(Cnt.LastName,'')AS [全名],
Ftm.FinTransTypeCode AS [Trans Type],
Ftm.FinTransCode AS [Trans Code],
Fm.FJNo AS [FJ No.],
Fm.ReversalFJNo AS [Reversal FJNo。],
CAST(ISNULL(Fm.FJAmt,0)AS DECIMAL(9,2))AS金额,
Ftc.InterfaceDescr AS [交易描述],
Fm.Comments,Fm.CreatedBy AS [发布者],
Ftm.Created,RegistrationTypeid,FJDate
来自FinMaster AS Fm
INNER JOIN FinTransMaster AS Ftm ON Ftm.FjNo = Fm.FJNo
INNER JOIN dbo.Account AS Act on Ftm.AcctID = Act.AccountId
INNER JOIN dbo.Contact AS Cnt ON Act.PrimaryContactId = Cnt.ContactId
INNER JOIN FinTransCodes AS Ftc ON Ftc.FinTransCode = Ftm.FinTransCode
left outer join FinMaster as FM2 on FM2.ReversalFjNo = Fm.FJNo and FM2.ReversalFjNo is null
left outer join FinTransMaster AS Ftm2 on (Ftm2.FjNo = Ftm.FjNo) AND (Ftm2.FjTransSeqNo < Ftm.FjTransSeqNo)
and Ftm2.FjNo is null
WHERE
(Ftm.FinTransTypeCode&lt;&gt;'PYMT')和FJDate&gt; getdate() - 5
按照Ftm.Created DESC订购