加入两个包含两个外键的表

时间:2012-06-26 22:41:11

标签: sql join foreign-keys

在编写SQL时,我非常业余,所以也许这对某人来说很容易? 我有两张表如下:

表1 - DeviceName,DeviceID,AlternateID

  • MyPhone,333,AAA
  • HerPhone,444,CCC

表2 - PhoneID,ProgramName

  • 333,AngryBirds
  • CCC,Evernote

如您所见,Table2使用Table1中的两种不同的PhoneID类型(DeviceID和AlternateID)。我正在寻找一个sql语句,它会产生如下输出:

  • MyPhone,AngryBirds
  • HerPhone,Evernote

感谢任何帮助。

干杯, 标记

2 个答案:

答案 0 :(得分:3)

SELECT deviceName, programName
FROM table2 t2
JOIN table1 t1
 ON(t1.DeviceID=t2.PhoneID OR t1.AlternateID=t2.PhoneID)

或(可读性较低但较短)

SELECT deviceName, programName
FROM table2 t2
JOIN table1 t1
 ON(t2.PhoneID IN (t1.DeviceID, t1.AlternateID))

但是,如果DeviceID和AlternateID来自同一个集合,您应该考虑重构数据库:如果设备可以有多个有效ID,而不仅仅是两个,该怎么办?

答案 1 :(得分:0)

如果表2中定义了333和AAA,该怎么办?我假设您只想要每个DeviceName返回一行,这意味着您需要使用外连接两次连接到表2:

select DeviceName, 
       t2a.ProgramName, 
       t2b.ProgramName as AltProgramName
  from table1 t1
  left outer join table2 t2a
    on t1.DeviceID = t2a.PhoneID
  left outer join table2 t2b
    on t1.AlternateID = t2b.PhoneID

如果您只想列出一个ProgramName,并且可以确定在两者都存在的情况下使用哪个ProgramName,您可以执行以下操作:(假设DeviceID胜过AlternateID)

select DeviceName, 
       coalesce(t2a.ProgramName, t2b.ProgramName) as AltProgramName
  from table1 t1
  left outer join table2 t2a
    on t1.DeviceID = t2a.PhoneID
  left outer join table2 t2b
    on t1.AlternateID = t2b.PhoneID

如果您希望第一个程序列始终包含值,并且只在第二列中列出值(如果两者都存在),那么

select DeviceName, 
       coalesce(t2a.ProgramName, t2b.ProgramName) as ProgramName1,
       case when t2a.ProgramName is not null then t2b.ProgramName end as ProgramName2
  from table1 t1
  left outer join table2 t2a
    on t1.DeviceID = t2a.PhoneID
  left outer join table2 t2b
    on t1.AlternateID = t2b.PhoneID


编辑

我认为该查询用于报告目的,在这种情况下,您很可能只需要每个设备一行。

我刚刚意识到为什么OP可能希望每台设备返回多行。如果查询用于定义按任一名称查找设备的视图,则需要多行。

Jan's answer非常适合查找视图。但是,根据数据库引擎的查询优化器和表的大小,它可能会也可能不会运行良好。如果表非常大,那么您将需要索引查找。具有OR条件的连接可能会阻止某些系统上的索引查找。使用UNION ALL的等效查询可以支持在更多系统上进行索引查找。

select DeviceName,
       ProgramName
  from table1 t1
  join table2 t2
    on t1.DeviceID = t2.PhoneID
union all
select DeviceName,
       ProgramName
  from table1 t1
  join table2 t2
    on t1.AlternateID = t2.PhoneID