Как сделать объединение нескольких таблиц в MySQL с использованием составных внешних ключей? - PullRequest
1 голос
/ 19 марта 2010

Примеры таблиц следующие:

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, но в итоге получается, что ALL юниты возвращаются с side из 1 потому что это всегда первая сторона, указанная для scenID в таблице SCENARIO_NATIONS.

Концептуально, я думаю, что должно произойти, это то, что SCENARIO_NATIONS должен быть присоединен как к scenID (чтобы ограничить его только этим сценарием), так и к nation каждого подразделения, но я понятия не имею, как сделай это.


Код OMG Ponies приводит к тому, что каждый юнит перечисляется дважды, по одному на сторону, а не только для той стороны, на которой находится его родительская нация:

[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

И чтобы мы изменили код следующим образом:

SELECT sn.side, snu.scenid, ubd.nation, ubd.unitname
FROM sn
JOIN snu 
        ON snu.scenid=sn.scenid AND snu.scenid = 'scenID'
JOIN ubd
        ON ubd.nation=sn.nation AND ubd.unitid=snu.unitid //double join is the key change
ORDER BY sn.side, ubd.nation, ubd.unitname

1 Ответ

2 голосов
/ 19 марта 2010

Если вы хотите только 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 - это значение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...