在SQL中查询外部联接

时间:2013-03-15 17:20:54

标签: sql sql-server left-join

我有一个包含地理信息的SQL数据库。该数据库有三个表:

PostalCode
----------
Code  (char(10))
StateID (uniqueidentifier)

State
-----
ID (uniqueidentifier)
Name (nvarchar(max))
CountryID (uniqueidentifier)

Country
-------
ID (uniqueidentifier)
Name

关系是:一个国家有国家。国家有邮政编码。我正在尝试创建一个查询,在那里我可以找到特定邮政编码所属国家/地区的所有州。目前,我正在尝试以下方法:

SELECT 
  s.*
FROM 
  [PostalCode] p, 
  [State] s,
  [Country] c
WHERE
  p.[Zip]='90028' AND 
  p.[StateID]=s.[ID] AND 
  s.[CountryID]=c.[ID]

不幸的是,这个结果返回1条记录(与加利福尼亚州相关的州记录)。然而,实际上,我需要它返回50条记录(美国每个州一条记录)。如何修改此查询以执行此操作?

谢谢

1 个答案:

答案 0 :(得分:3)

您使用的是INNER JOIN,需要将语法更改为LEFT JOIN

SELECT  s.*
FROM [State] s
LEFT JOIN [PostalCode] p
  ON p.[StateID]=s.[ID]
  AND p.[Zip]='90028'
LEFT JOIN [Country] c
  ON s.[CountryID]=c.[ID]

您会注意到我更改为使用ANSI JOIN语法,而不是使用逗号和WHERE子句加入表。

LEFT JOIN将返回state表中的所有行,即使其他表中没有匹配的行也是如此。

如果您想要返回邮政编码等于特定代码的国家/地区的所有州,则可以使用:

select s.*
from state s
inner join
(
  SELECT s.countryid
  FROM [State] s
  INNER JOIN [PostalCode] p
    ON p.[StateID]=s.[ID]
  INNER JOIN [Country] c
    ON s.[CountryID]=c.[ID]
  WHERE p.[Zip]='90028'
) c
  on s.countryid = c.countryid;

或者您可以使用:

select s1.*
from state s1
where exists (select s2.countryid
              from state s2
              inner join country c
                on s2.countryid = c.id
              inner join postalcode p
                on s2.id = p.stateid
              where p.zip = 90028
               and s1.countryid = s2.countryid)