2016-05-05 4 views
0

У меня проблемы с написанием этого запроса. Таблица A содержит ссылку на таблицу B1 ИЛИ на таблицу B2. Таблица B1 и B2 имеют ссылку 1 - 1 на таблицу C1 или C2, которая, в свою очередь, содержит ссылку на таблицу D. Я могу сделать это отдельно для B1 или B2, но не для обоих в том же запросе, и для кода сервера требуется, чтобы значения передавались по одному запросу.JOIN между резервными таблицами

нужно выбрать строки из таблицы А, которые должны быть подведены (с помощью логического поля), отделяя значения, сгруппированные по таблице D:

Name | SUM(ValueB1) | SUM(ValueB2) 
------------------------------------ 
NameD1 |   1552 |   654 
NameD2 |   564 |   564 
NameD3 |   645 |   984 

Я попытался это:

SELECT 
    tableD.NameD AS Name, 
    SUM(IF(tableA.Type = 'B1', tableB1,ValueB1, 0)), 
    SUM(IF(tableA.Type = 'B2', tableB2,ValueB2, 0)) 
FROM tableA 
INNER JOIN tableB1 ON tableA.ID_tableB1 = tableB1.ID_tableB1 
INNER JOIN tableC1 ON tableB1.ID_tableC1 = tableC1.ID_tableC1 
INNER JOIN tableD ON tableC1.ID_tableD = tableD.ID_tableD 
INNER JOIN tableB2 ON tableA.ID_tableB2 = tableB1.ID_tableB2 
INNER JOIN tableC2 ON tableB2.ID_tableC2 = tableC2.ID_tableC2 
INNER JOIN tableD ON tableC2.ID_tableD = tableD.ID_tableD 
WHERE tableA.Boolean = 'sum' 
GROUP BY tableD.ID_tableD 

TABLE A 
--------------- 
- ID_tableA 
- ID_tableB1 
- ID_tableB2 
- Type (B1 or B2) 
- Boolean (sum/not sum) 
- OtherFields 

TABLE B1 
--------------- 
- ID_tableB1 
- ID_tableC1 
- ValueB1 
- OtherFields 

TABLE B2 
--------------- 
- ID_tableB2 
- ID_tableC2 
- ValueB2 
- OtherFields 

TABLE C1 
--------------- 
- ID_tableC1 
- ID_tableD 

TABLE C2 
--------------- 
- ID_tableC2 
- ID_tableD 

TABLE D 
--------------- 
- ID_tableD 
- NameD 

Проблема для меня состоит в том, чтобы ссылаться два раза «Таблица D». Я не могу использовать псевдоним и возиться с запросом, я не получаю ничего или только один столбец суммы. :/

Я получаю сообщение об ошибке «Код ошибки: 1066. Не уникальный стол/псевдоним»

+0

Я пытаюсь с UNION – Fehu

ответ

1

Поскольку у вас есть внесенная в два раза, так что вы просто должны дать ему другое имя, например, d1 и d2 (то есть то, что сообщение об ошибке говорит вам):

... 
FROM tableA 
LEFT OUTER JOIN tableB1 ON tableA.ID_tableB1 = tableB1.ID_tableB1 
INNER JOIN tableC1 ON tableB1.ID_tableC1 = tableC1.ID_tableC1 
INNER JOIN tableD d1 ON tableC1.ID_tableD = d1.ID_tableD 
LEFT OUTER JOIN tableB2 ON tableA.ID_tableB2 = tableB2.ID_tableB2 
INNER JOIN tableC2 ON tableB2.ID_tableC2 = tableC2.ID_tableC2 
INNER JOIN tableD d2 ON tableC2.ID_tableD = d2.ID_tableD 
WHERE tableA.Boolean = 'sum' 
... 

И вы должны использовать внешнее соединение для A-B1 и A-B2, так как один из них, вероятно, не будет существовать.

Но на самом деле, я хотел бы предложить вам использовать союз:

select NameD AS Name, sum(ValueB1), sum(ValueB2) 
from (
    SELECT tableA.boolean, tableD.ID_tableD, tableD.NameD, tableB1.ValueB1 as ValueB1, 0 as ValueB2 
    FROM tableA 
    INNER JOIN tableB1 ON tableA.ID_tableB1 = tableB1.ID_tableB1 
    INNER JOIN tableC1 ON tableB1.ID_tableC1 = tableC1.ID_tableC1 
    INNER JOIN tableD ON tableC1.ID_tableD = tableD.ID_tableD 
    union all 
    SELECT tableA.boolean, tableD.ID_tableD, tableD.NameD, 0, tableB2.ValueB2 
    FROM tableA 
    INNER JOIN tableB2 ON tableA.ID_tableB2 = tableB2.ID_tableB2 
    INNER JOIN tableC2 ON tableB2.ID_tableC2 = tableC2.ID_tableC2 
    INNER JOIN tableD ON tableC2.ID_tableD = tableD.ID_tableD 
) as sq 
WHERE sq.Boolean = 'sum' 
GROUP BY sq.ID_tableD, sq.NameD 

, так как это делает его более ясным, что вы присоединяетесь (читателю и оптимизатор) и, самое главное, мешает вам суммированием вещи дважды если запись в A будет иметь ссылку как на таблицу B1, так и на таблицу B2 (если это возможно в вашей модели).

Смежные вопросы