仅存在一个匹配时的内部联接

时间:2013-06-13 15:00:39

标签: sql

考虑以下实际情况:

你有一个城镇表,但想查找相应的邮政编码    这些城镇的代码。在大多数情况下,这很容易做到    每个城镇只有一个邮政编码,但在交易时也有例外    与城市。

你有两张桌子:

CONTACT
Town          | Zip
--------------+----
Ft Washington | NULL
Ambler        | NULL
Media         | NULL
Ambler        | NULL
New York      | NULL

CITIES_EXTENDED
Town          | Zip
--------------+----
Ft Washington | 19034
Ambler        | 19002
Media         | 19063
New York      | 10101
New York      | 10102
New York      | 10103
New York      | 10104

INNER JOIN将返回New York四行。这显然是不可取的,因为该数据本质上是不准确的。

所需结果如下:

Town          | Zip
--------------+----
Ft Washington | 19034
Ambler        | 19002
Media         | 19063
Ambler        | 19002
New York      | NULL

实现这一目标的最佳方式是什么?

2 个答案:

答案 0 :(得分:3)

这会解决您的问题吗?

select ce.Town, 
case when count(*) > 1 then null else Max(c.Zip) end as Zip
from CITIES_EXTENDED ce
    inner join CONTACT c
        on ce.Town = c.Town
    group by ce.Town

Max()函数可以正常工作,因为c.Zip只有一个值。

答案 1 :(得分:1)

尝试:

Select  a.Town,
        b.zip
FROM    contact a
INNER JOIN cities_extended b ON a.Town = b.Town
WHERE a.Town NOT IN (
    SELECT  Town
    FROM    (
        Select  Town,
                COUNT(*)
        From    cities_extended
        Group by Town
        HAVING COUNT(*) > 1
    ) T
)

UNION ALL 

Select  DISTINCT
        a.Town,
        NULL
FROM    contact a
INNER JOIN  cities_extended b ON a.Town = b.Town
WHERE   a.Town IN (
    SELECT  Town
    FROM    (
        Select  Town,
                COUNT(*)
        From    cities_extended
        Group by Town
        HAVING COUNT(*) > 1
    ) T
)

查看我的Demo

这可能不是一个优雅的解决方案,但这可以按照您的要求完成工作; - )