在冗余表之间加入

时间:2016-05-05 10:48:49

标签: mysql join

我在编写此查询时遇到问题。 表A包含对表B1 OR 到表B2的引用。 表B1和B2对表C1或C2有1对1的引用,而表C1或C2又包含对表D的引用。 我可以单独为B1或B2执行此操作,但在同一查询中不能同时执行,并且服务器代码要求通过单个查询传递值。

我需要从表A中选择必须求和的行(通过布尔字段),分隔按表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。不是唯一的表/别名”

1 个答案:

答案 0 :(得分:1)

由于你有两次TableD,所以你只需给它一个不同的名字,例如d1d2(这是错误消息告诉您的内容):

...
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使用外连接,因为其中一个可能不存在。

但实际上,我建议您使用union:

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(如果是这在您的模型中是可能的。)