JOINS 的大型查询中的 SQL 子查询链
Posted
技术标签:
【中文标题】JOINS 的大型查询中的 SQL 子查询链【英文标题】:Chain of SQL subqueries within large query of JOINS 【发布时间】:2018-02-21 18:06:16 【问题描述】:我正在尝试使用复杂的嵌套选择操作构建 SQL 查询!
我原来的SQL查询成功加入了大约30个表,数据按要求检索!然而,30 个表中的每条获取记录 在另一个名为 (Comments) 的表中有许多记录!我想要做的是将(评论表)中的每条记录归因于它在另一个记录中的记录 按 ID 列出 30 个表,并在一个查询中一起检索它们。然而,这不是唯一的挑战,30 张表中的一些表除了 (评论表)另一个名为(附加)的表中的更多记录,所以我正在寻找主子查询中的附加子查询 外部主查询中的 LEFT JOIN。
让思路更清晰;如果没有子查询,脚本将如下所示:
$query = $mysqli->query("
SELECT
parent1.parent1_id,
parent1.child1_id,
parent1.child2_id,
parent1.child3_id,
parent2.parent2_id,
parent2.child1_id,
parent2.child2_id,
parent2.child3_id,
child1.child1_id,
child1.child1_content,
child2.child2_id,
child2.child2_content,
child3.child3_id,
child3.child3_content
FROM
parent1
LEFT JOIN child1
ON child1.child1_id = parent1.child1_id
LEFT JOIN child2
ON child2.child2_id = parent1.child2_id
LEFT JOIN child3
ON child3.child3_id = parent1.child3_id
LEFT JOIN followers
ON parent1.user_id = followers.followed_id
AND parent1.parent1_timestamp > followers.followed_timestamp
AND parent1.parent1_id NOT IN (SELECT removed.isub_rmv FROM removed)
AND parent1.parent1_hide = false
WHERE
followers.follower_id = $_SESSION['info']
$portname_clause
ORDER BY
parent1.parent1_timestamp DESC
LIMIT
$postnumbers
OFFSET
$offset
")
// Now fetching and looping through the retrieved data
while($row = $query->fetch_assoc())
echo $row['child1_content'];
$subquery1 = $mysqli->query("SELECT extras.child1_id,
extras.extrasContent FROM extras WHERE extras.child1_id =
$row['child1_id']");
while($row1 = $subquery1->fetch_assoc())
echo $row1['extrasContent'];
echo $row['child2_content'];
$subquery2 = $mysqli->query("SELECT extras.child2_id,
extras.extrasContent FROM extras WHERE extras.child2_id =
$row['child2_id']");
while($row2 = $subquery2->fetch_assoc())
echo $row2['extrasContent'];
echo $row['child3_content'];
$subquery3 = $mysqli->query("SELECT extras.child3_id,
extras.extrasContent FROM extras WHERE extras.child3_id =
$row['child3_id']");
while($row3 = $subquery3->fetch_assoc())
echo $row3['extrasContent'];
// Here i need to run additional query inside the subquery 3 to retrieve the (Comments table) data beside (extras table)
$subquery4 = $mysqli->query("SELECT comments.comment_id, comments.comment FROM comments WHERE comments.child3_id = $row['child3_id'] OR comments.child3_id = $row3['child3_id']");
while($row4 = $subquery4->fetch_assoc())
echo $row4['comment'];
// No sane person would make such code
因为上面的代码完全是可笑的,所以我搜索了一种更好的方法来执行它,这就是我遇到子查询的地方 概念,但是我对子查询一无所知,并且在我研究它后不久我想出了这个凌乱的代码,请在下面查看!
我没有在这里发布原始代码,因为它太长了,我包括一个我想要应用的表的虚拟示例 查询以演示该过程。
SELECT
parent1.parent1_id,
parent1.child1_id,
parent1.child2_id,
parent1.child3_id,
parent2.parent2_id,
parent2.child1_id,
parent2.child2_id,
parent2.child3_id
FROM
parent1
LEFT JOIN
( SELECT
child1.child1_id,
child1.child1_content
FROM
child1
WHERE
child1.child1_id = parent1.child1_id ) child1
( SELECT extras.extrasID, extras.extrasContent
FROM
extras
WHERE
extras.child1_id = child1.child1_id )
ON parent1.child1_id = child1.child1_id
LEFT JOIN child2
( SELECT
child2.child2_id,
child2.child2_content
FROM
child2
WHERE
child2.child2_id = parent1.child2_id )
( SELECT
extras.extrasID,
extras.extrasContent
FROM
extras
WHERE
extras.child2_id = child2.child2_id )
ON parent1.child2_id = child2.child2_id
LEFT JOIN child3
( SELECT
child3.child3_id,
child3.child3_content
FROM
child3
WHERE
child3.child3_id = parent1.child3_id )
( SELECT
extras.extrasID,
extras.extrasContent
FROM
( SELECT
comments.comment_id,
comments.comment
FROM
comments
WHERE
comments.child3_id = extras.child3_id ) extras
JOIN child3
ON extras.child3_id = child3.child3_id )
ON parent1.child3_id = child3.child3_id
LEFT JOIN followers
ON parent1.user_id = followers.followed_id
AND parent1.parent1_timestamp > followers.follower_timestamp
AND parent1.parent1_id NOT IN (SELECT removed.isub_rmv FROM removed)
AND parent1.parent1_hide = false
WHERE
followers.follower_id = $_SESSION['info']
$portname_clause
ORDER BY
parent1.parent1_timestamp DESC
LIMIT
$postnumbers
OFFSET
$offset // <-- Sorry for the bad code formatting!
我正在使用 MySql 5.6.37
我还没有掌握子查询概念的窍门,坦率地说,我在研究它时迷失了方向,并且由于下面的注释中也提到了另一个原因。
注意:我提前道歉,我可能无法立即回复,因为我住的地方没有电、ADSL 或电话,而且我的 USB 调制解调器几乎没有信号,我每天只有两个小时平均三个小时由 desil 发电机产生的电能。我充电 我的笔记本电脑和上网,剩下的一两个小时用于其他生活用品。 我知道这个笑话在我身上,因为我正在开发一个没有电或永久互联网的网络项目。但生活并不能给予一切!哈哈。
【问题讨论】:
***.com/q/48856576/905902 您重复了之前查询中的错误。例如:) child1 ( SELECT extras
是第一个错误。先修好了。
Complex Nested SQL Query的可能重复
我正在努力,请耐心等待。
@wildplasser 我发布了我的解决方案,看看吧。
【参考方案1】:
这就是我解决问题的方法!
SELECT
parent1.parent1_id,
parent1.child1_id,
child1.child1_id,
child1.child1_content,
comments.comment_id,
comments.comment,
comments.child1_id
FROM parent1 LEFT JOIN
(
SELECT comments.comment_id, comments.comment, comments.child1_id
FROM
(
SELECT comments.comment_id,comments. comment, comments.child1_id
FROM comments
) comments JOIN child1
ON comments.child1_id = child1.child1_id
) comments
ON child1.child1_id = comments.
它需要一些别名,然后就可以了。
【讨论】:
以上是关于JOINS 的大型查询中的 SQL 子查询链的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JOINS 和嵌套 SELECT 优化此 SQL 查询?