如何在涉及复合外键的MySQL中进行多表连接?

时间:2010-03-19 04:44:18

标签: sql mysql join

示例表如下:

SCENARIO_NATIONS
[scenID]  [side]  [nation]

scen001     1     Germany
scen001     2     Britain
scen001     2     Canada

SCENARIO_NEEDUNITS
[scenID]  [unitID]

scen001    0001
scen001    0003
scen001    0107
scen001    0258
scen001    0759

UNIT_BASIC_DATA
[unitID]  [nation]  [name]

  0001    Germany   Mortars
  0003    Germany   Infantry
  0107    Britain   Lt
  0258    Britain   Infantry
  0759    Canada    Kilted Yaksmen

目标:给定scenID,从数据库中提取按side, nation, name排序的单位列表。

我可以做除side包含之外的所有内容:

SELECT scenario_needunits.scenID, unit_basic_data.nation, unit_basic_data.name
FROM scenario_needunits
LEFT OUTER JOIN unit_basic_data
ON scenario_needunits.unitID=unit_basic_data.unitID
WHERE scenario_needunits.scenID='scen001'
ORDER BY unit_basic_data.nation ASC, unit_basic_data.name ASC

我尝试将SCENARIO_NATIONS表格放在LEFT OUTER JOIN scenID上,但最终发生的是所有单位返回时side的{​​{1}},因为它始终是1表中scenID列出的第一面。

从概念上讲,我认为需要发生的是SCENARIO_NATIONS必须加入SCENARIO_NATIONS(将其限制为仅适用于该情景)和每个单位scenID,但我不喜欢我知道怎么做。


OMG Ponies的代码导致每个单元被列出两次,每侧一次,而不仅仅是其父国所在的一侧:

nation

正确的结果将是

[scenID]  [side]   [nation]   [name]
BaBu001     1   America   CAPT
BaBu001     1   America   HMG
BaBu001     1   Germany   CAPT
BaBu001     1   Germany   GREN
BaBu001     2   America   CAPT
BaBu001     2   America   HMG
BaBu001     2   Germany   CAPT
BaBu001     2   Germany   GREN

为此,我们修改代码如下:

[scenID]  [side]   [nation]   [name]
BaBu001     1   America   CAPT
BaBu001     1   America   HMG
BaBu001     2   Germany   CAPT
BaBu001     2   Germany   GREN

1 个答案:

答案 0 :(得分:2)

如果您只想在UNIT_BASIC_DATA表中使用SCENARIO_NEEDUNITS行/记录,请使用:

  SELECT snu.scenid,
         sn.side,
         ubd.nation,
         ubd.name
    FROM UNIT_BASIC_DATA ubd
    JOIN SCENARIO_NEEDUNITS snu ON snu.unitid = ubd.unitid
                               AND snu.scenid = ?
    JOIN SCENARIO_NATIONS sn ON sn.scenid = snu.scenid
ORDER BY snu.scenid, sn.side, ubd.nation, ubd.name

?替换为您要查找的scenid

您无需指定ASC - 这是默认设置。