从2个查询而不是表中获取丢失的记录

时间:2013-04-08 14:18:42

标签: sql sql-server sql-server-2008

我知道如何找到缺少但只有两个查询的表之间的公共值?

查询1:

SELECT DISTINCT GENG.GlGroup
FROM MCMGenHistory GENH 
    RIGHT OUTER JOIN RPZCGenGroup GENG 
        ON GENG.ExpenseCode = substring(GENH.GlCode,13,3)
WHERE SUBSTRING(GENH.GlCode,1,1)='P'

结果:

10
7
8
5
1
6
9
4

查询2:

SELECT DISTINCT GENG.GlGroup 
from RPZCGenGroup GENG

结果:

1
10
2
3
4
5
6
7
8
9

我想要丢失的记录,例如2和3.问题是第一个查询使用相同的表,但使用过滤器。

2 个答案:

答案 0 :(得分:5)

当您在JOIN条件之外添加条件时,有效地将OUTER JOIN转换为INNER JOIN。如果我理解正确你想要加入条件的GENG.GlGroup值不适用,那么为什么不在OUTER JOIN逻辑中保留所有剔除标准并从RPZCGenGroup获取GENH.GlGroup为空的记录? / p>

SELECT  DISTINCT GENG.GlGroup
FROM    MCMGenHistory GENH 
RIGHT   OUTER JOIN RPZCGenGroup GENG 
        ON  GENG.ExpenseCode=substring(GENH.GlCode,13,3)
        AND SUBSTRING(GENH.GlCode,1,1)='P'
WHERE   GENH.GlCode Is Null 

答案 1 :(得分:2)

假设您希望 Query 2 的结果中的所有记录都不在 Query 1 的结果中,那么快速简便的方法就是使用EXCEPT

[Query 2]
EXCEPT
[QUERY 1]

具体做法是:

SELECT DISTINCT GENG.GlGroup 
FROM RPZCGenGroup GENG
EXCEPT
SELECT GENG.GlGroup
FROM MCMGenHistory GENH 
    RIGHT OUTER JOIN RPZCGenGroup GENG 
        ON GENG.ExpenseCode = substring(GENH.GlCode,13,3)
WHERE SUBSTRING(GENH.GlCode,1,1)='P'

您可能不希望在第二个查询中使用DISTINCT,因为它可能会降低性能并且对结果没有影响。

进一步的文档:EXCEPT and INTERSECT @ MSDN

看起来你真正追求的是 RPZCGenGroup 中的所有记录, MCMGenHistory 中没有任何匹配记录,其中GlCode以'P开头”。快速简便的版本是使用NOT EXISTS

SELECT GENG.GlGroup 
FROM RPZCGenGroup GENG
WHERE NOT EXISTS (
    SELECT 
    FROM MCMGenHistory GENH
    WHERE substring(GENH.GlCode,13,3) = GENG.ExpenseCode
        AND SUBSTRING(GENH.GlCode,1,1)='P'
)

NOT EXISTS的性能可能是一个问题,因此您可以/应该使用正确的外部联接替换它(请注意@ Love2Learn的评估):

SELECT GENG.GlGroup 
FROM RPZCGenGroup GENG
    LEFT OUTER JOIN MCMGenHistory GENH
        ON substring(GENH.GlCode,13,3) = GENG.ExpenseCode
            AND SUBSTRING(GENH.GlCode,1,1)='P'
WHERE GENH.GlCode IS NULL