长级联MySQL查询

时间:2016-09-14 16:37:11

标签: mysql sql select

我有一个查询链接到四个深度表:

这是一个例子:

CREATE TABLE `TableA` 
(
  `ID` int(11) NOT NULL,
  `ValueA` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `TableA` (`ID`, `ValueA`) 
VALUES (1, 20), (2, 30); 

CREATE TABLE `TableB` 
(
  `ID` int(11) NOT NULL,
  `ValueB` int(11) NOT NULL,
  `TableA_ID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `TableB` (`ID`, `ValueB`, `TableA_ID`) 
VALUES (1, 40, 2), (2, 60, 1);

CREATE TABLE `TableC` 
(
  `ID` int(11) NOT NULL,
  `ValueC` int(11) NOT NULL,
  `TableB_ID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `TableC` (`ID`, `ValueC`, `TableB_ID`) 
VALUES (1, 101, 2), (2, 102, 1);

CREATE TABLE `TableD`
(
  `ID` int(11) NOT NULL,
  `ValueD` int(11) NOT NULL,
  `TableC_ID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `TableD` (`ID`, `ValueD`, `TableC_ID`) 
VALUES (1, 200, 1), (2, 100, 2);

ALTER TABLE `TableA`
  ADD PRIMARY KEY (`ID`);

ALTER TABLE `TableB`
  ADD PRIMARY KEY (`ID`),
  ADD UNIQUE KEY `TableB_ak_1` (`TableA_ID`),
  ADD CONSTRAINT `TableB_TableA` FOREIGN KEY (`TableA_ID`) REFERENCES `TableA` (`ID`);

ALTER TABLE `TableC`
  ADD PRIMARY KEY (`ID`),
  ADD UNIQUE KEY `TableC_ak_1` (`TableB_ID`),
  ADD CONSTRAINT `TableC_TableB` FOREIGN KEY (`TableB_ID`) REFERENCES `TableB` (`ID`);

ALTER TABLE `TableD`
  ADD PRIMARY KEY (`ID`),
  ADD UNIQUE KEY `TableD_ak_1` (`TableC_ID`),
  ADD CONSTRAINT `TableD_TableC` FOREIGN KEY (`TableC_ID`) REFERENCES `TableC` (`ID`);

它们与唯一约束相关联。所以基本上对于TableD中的每个ID,我都会从tableA获得一个值。

现在,除了运行以下查询之外,获取此信息的正确方法是什么:

mysql> select ValueA from TableA where ID = (select TableA_ID from TableB where ID = (select TableB_ID from TableC where ID = (Select TableC_ID from TableD where ID = 1)));
+--------+
| ValueA |
+--------+
|     20 |
+--------+

2 个答案:

答案 0 :(得分:1)

实现这一目标的最简单方法是IMHO,即使用连接:

SELECT valueA
FROM   tableA
JOIN   tableB on tableB.tableA_id = tablea.id
JOIN   tableC on tableC.tableB_id = tablec.id
JOIN   tableD on tableD.tableC_id = tabled.id
WHERE  tabled.id = 1

答案 1 :(得分:1)

你是对的,你对所有子查询的查询都很荒谬。

SELECT ValueA FROM TableA 
WHERE ID = (SELECT TableA_ID FROM TableB WHERE ID = 
            (SELECT TableB_ID FROM TableC WHERE ID = 
             (SELECT TableC_ID FROM TableD WHERE ID = 1)));

如果你要使用SQL,你真的需要学会使用JOINJOIN是一项基本操作。在SQL中避免JOIN就像在大多数其他语言中避免while循环一样。

这是使用JOIN语法的等效查询。

SELECT ValueA
FROM TableA
JOIN TableB ON TableA.ID = TableB.TableA_ID
JOIN TableC ON TableB.ID = TableC.TableB_ID
JOIN TableD ON TableC.ID = TableD.TableC_ID
WHERE TableD.ID = 1;

以下是演示:http://sqlfiddle.com/#!9/34503/2