SQL - 两个外部联接

时间:2009-08-03 23:55:36

标签: sql

我有一张代表国家/地区列表的表格。我有另一个表代表状态列表的表。我有另一张表代表省份列表的表格。由于数据定义不佳,一些州实际上在省表中,反之亦然。无论如何,每个省和州都与一个国家有关。

我需要基本上做一个双左外连接。我的问题是,我该怎么做?以下是我目前正在尝试的内容:

select
  c.Name as 'CountryName',
  ISNULL(p.[Name], '') as 'ProvinceName',
  ISNULL(s.[Name], '') as 'StateName'
from
  Country c 
    left outer join [Province] p on p.[CountryID]=c.[ID]
    left outer join [State] s on s.[CountryID]=c.[ID]

请注意,我需要做一些类似于两个左外连接的东西。这是我正在尝试的查询的简化版本。谢谢你的帮助!

6 个答案:

答案 0 :(得分:3)

你可以按照你说的方式去做。这没什么不对。我不一定用空字符串替换NULL。你有没有理由这样做?

在进行基本上两个一对多连接的时候你需要注意的是结果是乘法的。我的意思是,如果一个国家在省表中有3个条目,在州表中有4个条目,那么你将获得该国家的12行。

在这种情况下做一个UNION可能更合适。例如:

SELECT
  c.Name AS 'CountryName',
  '' AS 'ProvinceName',
  ISNULL(s.[Name], '') AS 'StateName'
FROM Country c 
LEFT OUTER JOIN [Province] p ON p.[CountryID]=c.[ID]
UNION ALL
SELECT
  c.Name AS 'CountryName',
  ISNULL(p.[Name], '') AS 'ProvinceName',
  '' AS 'ProvinceName'
FROM Country c 
LEFT OUTER JOIN [State] s ON s.[CountryID]=c.[ID]

只是一种可能性。这实际上取决于您的数据是什么样的以及您希望最终结果是什么。

答案 1 :(得分:2)

LEFT OUTER JOIN只是一个LEFT JOIN,语法很简单:

SELECT c.Name AS CountryName
p.Name AS ProvinceName
s.Name AS StateName
FROM Country c
LEFT JOIN Province p ON p.CountryID = c.ID
LEFT JOIN State s ON s.CountryID = c.ID

答案 2 :(得分:0)

我猜你想把各省和州联系在一张桌子里。为此,您需要union运算符。我还添加了一个列RegionType,对于省份为0,对于州为1。您可能希望将此模式应用于在最终查询中区分这两种模式。

尝试类似:

SELECT c.Name as CountryName, p.Name as RegionName, 0 as RegionType
FROM Country c
LEFT OUTER JOIN Province p on c.ID = p.CountryID
UNION ALL
SELECT c.Name as CountryName, s.Name as RegionName, 1 as RegionType
FROM Country c
LEFT OUTER JOIN State s on s.ID = p.CountryID

答案 3 :(得分:0)

虽然您的实施涵盖各州和省,但地区情况如何(例如加拿大有地区和地区)?对于“行政区域”,可能会有一个表更好,而对于包含“州”,“省”,“领土”等的区域类型,可能会更好。 大多数情况下,您不会关心它是什么类型的地区,只是国家ID,地区ID和地区名称。

select
c.Name as 'CountryName',
ISNULL(r.[Name], '') as 'RegionName'
from
Country c 
left outer join [Regions] r on r.[CountryID]=c.[ID]

答案 4 :(得分:0)

听起来你的问题是你有两个表需要被视为一个表 - 即UNION ALL。那怎么样:

SELECT 
    c.Name as Country
   ,ps.Name as StateOrProvince
FROM        Country c
LEFT JOIN   (SELECT CountryID, Name FROM Province UNION ALL SELECT CountryID, Name FROM State) ps
    ON ps.CountryID = c.ID
;

罗布

答案 5 :(得分:0)

我终于能够理解这一点。您可以根据需要堆叠任意数量的外连接,关键是将所有where限定符放在外连接线上,这样就不会丢失所有空值。请参见下文,其中agldimension的所有限定符都包含在同一行中,而不是在where语句中。

select distinct
act.account, 
act.[description],
rul.[description],
att1.att_name,
att2.att_name,
att3.att_name,
att4.att_name,
att5.att_name,
att6.att_name,
att7.att_name
from aglaccounts act, aglrules rul  
full outer join agldimension att1 on rul.att_1_id = att1.attribute_id and att1.[status] = 'N' and att1.client = 'PH' 
full outer join agldimension att2 on rul.att_2_id = att2.attribute_id and att2.[status] = 'N' and att2.client = 'PH'
full outer join agldimension att3 on rul.att_3_id = att3.attribute_id and att3.[status] = 'N' and att3.client = 'PH'
full outer join agldimension att4 on rul.att_4_id = att4.attribute_id and att4.[status] = 'N' and att4.client = 'PH'
full outer join agldimension att5 on rul.att_5_id = att5.attribute_id and att5.[status] = 'N' and att5.client = 'PH'
full outer join agldimension att6 on rul.att_6_id = att6.attribute_id and att6.[status] = 'N' and att6.client = 'PH'
full outer join agldimension att7 on rul.att_7_id = att7.attribute_id and att7.[status] = 'N' and att7.client = 'PH'
where 
act.account_rule = rul.account_rule and act.client = 'PH' and act.[status] = 'N'