将表连接到自身以比较两种不同类型的字段

时间:2012-01-05 21:06:40

标签: sql sql-server sql-server-2005 tsql

抱歉这个令人困惑的标题。

我有两个表,individuorgcontindividu看起来像:

individu
-------------
ind_id
org_id
email

orgcont看起来像:

orgcont
-------------
ind_id
function_code

我有许多用户可以属于同一个org_id,并且每个用户都有自己的ind_id。 org_id的“领导者”的功能代码为“PRIM”,其他人都无关紧要。我正在尝试返回所有拥有'PRIM'org_id的用户的emailfunction code列表,这些用户的用户具有非'PRIM'的NULL电子邮件地址。

我有类似的东西,但结果不正确。任何帮助将不胜感激:

select
    i.email,
    i.org_id
from
    individu i,
    orgcont o,
    individu i2,
    orgcont o2
where
    i.ind_id = o.ind_id
    and i.org_id = i2.org_id
    and i2.ind_id = o2.ind_id
    and o.function_code = 'PRIM'
    and o2.function_code != 'PRIM'
    and i2.email is NULL

2 个答案:

答案 0 :(得分:2)

使用exists

进行尝试
select
    i.email,
    i.org_id
from
    individu i
    inner join orgcont o on
        i.ind_id = o.ind_id
where
    o.function_code = 'PRIM'
    and exists (
        select
            1
        from
            individu i2
            inner join orgcont o2 on
                i2.ind_id = o2.ind_id
        where
            i2.org_id = i.org_id
            and o2.function_code != 'PRIM'
            and i2.email is null
    )

对于每个领导者,只会在其组织中使用null电子邮件地址向您返回一行,而不是原始查询,这将返回重复的行。

另请注意加入语法 - 您希望在此处inner join而不是cross join,因此请明确这样做。

此外,您可能刚刚完成select distinct,但这比exists贵一点。

答案 1 :(得分:0)

这应该有效,子查询的 INNER JOIN 将作为过滤器

SELECT DISTINCT i.email, i.org_id
FROM individu i 
     INNER JOIN orgcont o ON i.ind_id = o.ind_id
     INNER JOIN 
     (  SELECT i.id
        FROM individu i 
             INNER JOIN orgcont o ON i.ind_id = o.ind_id
        WHERE o.function_code != 'PRIM' AND i.email IS NULL 
     ) t ON t.id = i.id
WHERE o.function_code = 'PRIM'