1

正如我们所知,LEFT JOIN SQL 语句给出了 LEFT 表中的所有值,并通过右表中的 id(外键)给出了联合值。例如,我有下表

comments
    comment_id
    parent_id
    comment_body

该表有以下数据

-----------|-----------|-------------------|
comment_id | parent_id | comment_body      |
-----------|-----------|-------------------|
1          | NULL      | parent comment    | 
-----------|-----------|-------------------|
2          | 1         | child comment     | 
-----------|-----------|-------------------|
3          | NULL      | parent comment    | 
-----------|-----------|-------------------|
4          | 1         | child comment     | 
-----------|-----------|-------------------|
5          | 3         | child comment     | 
-----------|-----------|-------------------|
6          | 1         | parent comment    | 
-----------|-----------|-------------------|
7          | NULL      | parent comment    | 
-----------|-----------|-------------------|
8          | 1         | child comment     | 
-----------|-----------|-------------------|
9          | 7         | child comment     | 
-----------|-----------|-------------------|
10         | 3         | child comment     | 
-----------|-----------|-------------------|

例如,我在上表中运行以下查询

SELECT c1 . * , c2 . * 
FROM comments c1
LEFT JOIN comments c2 ON c2.parent_id = c1.comment_id
WHERE c1.parent_id IS NULL 

它将给出以下输出

-----------|-----------|---------------|------------|-----------|---------------|
comment_id | parent_id | comment_body  | comment_id | parent_id | comment_body  |
-----------|-----------|---------------|------------|-----------|---------------|
1          | NULL      |parent comment | 1          | 1         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|
1          | NULL      |parent comment | 4          | 1         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|
1          | NULL      |parent comment | 6          | 1         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|
1          | NULL      |parent comment | 8          | 1         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|
3          | NULL      |parent comment | 5          | 3         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|
3          | NULL      |parent comment | 10         | 3         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|
7          | NULL      |parent comment | 9          | 7         | child comment |
-----------|-----------|---------------|------------|-----------|---------------|

在这里,我强调了价值观,这是额外的,我不需要它们。

在此处输入图像描述

在我看来,这些额外的值可能会提高性能。我可以得到以下格式的输出吗

在此处输入图像描述

如果不可能,请指导我上述查询的优缺点是什么?我应该使用它还是不使用它?

4

3 回答 3

1

你不能做这个。但这里有一个替代品

SELECT 
    c1 . * , 
    GROUP_CONCAT(c2.comment_id) AS comment_ids,
    GROUP_CONCAT(c2.parent_id) AS parent_ids,
    GROUP_CONCAT(c2.comment_body) AS comment_bodies
FROM comments c1
LEFT JOIN comments c2 ON c2.parent_id = c1.comment_id
WHERE c1.parent_id IS NULL

这将为您提供这种形式的输出

-----------|-----------|---------------|------------|-----------|-----------------------------------------------------------|
comment_id | parent_id | comment_body  | comment_id | parent_id | comment_body                                              |
-----------|-----------|---------------|------------|-----------|-----------------------------------------------------------|
1          | NULL      |parent comment | 1,4,6,8    | 1,1,1,1   | child comment , child comment ,child comment,child comment|
-----------|-----------|---------------|------------|-----------|-----------------------------------------------------------|
3          | NULL      |parent comment | 5,10       | 3,3       | child comment ,child comment                              |
-----------|-----------|---------------|------------|-----------|-----------------------------------------------------------|
7          | NULL      |parent comment | 9          | 7         | child comment                                             |
-----------|-----------|---------------|------------|-----------|-----------------------------------------------------------|

您可以使用 php explode 函数分解列,以将逗号分隔值转换为数组。

MySQL GROUP_CONCAT

于 2013-04-10T09:04:13.227 回答
0

您还可以使用更多子查询示例:

SELECT 
    IF(c2.comment_id = c4.first_child, c1.comment_id, NULL) AS comment_id,
    IF(c2.comment_id = c4.first_child, c1.parent_id, NULL) AS parent_id,
    IF(c2.comment_id = c4.first_child, c1.comment_body, NULL) AS comment_body,
   c2.*
FROM comments c1
LEFT JOIN comments c2 ON c2.parent_id = c1.comment_id
LEFT JOIN ( select c3.parent_id, MIN(c3.comment_id) AS first_child from comments as c3 WHERE c3.parent_id IS NOT NULL GROUP BY c3.parent_id ) as c4 ON (c4.parent_id = c2.parent_id)
WHERE c1.parent_id IS NULL;

示例输出:

comment_id | parent_id | comment_body   | comment_id | parent_id | comment_body
1          | NULL      | Parent Comment | 2          | 1         | Child Comment
NULL       | NULL      | NULL           | 4          | 1         | Child Comment
NULL       | NULL      | NULL           | 6          | 1         | Child Comment
NULL       | NULL      | NULL           | 8          | 1         | Child Comment
3          | NULL      | Parent Comment | 5          | 3         | Child Comment
NULL       | NULL      | NULL           | 10         | 3         | Child Comment
7          | NULL      | Parent Comment | 9          | 7         | Child Comment

当然,如果你想要性能,那么这些东西对你没有帮助。它不会使您的查询更快。

因为您也标记了标记 PHP,并且希望以低 cpu/内存使用率运行快速查询,并且使用较少的带宽(如果 mysql 服务器不在本地主机中)。那么可能最明智的做法是进行几个查询,如果表更大,只询问你真正需要从 mysql 得到什么。可能您不想一次获得所有父母和孩子的评论。当您的孩子评论也是其他评论的父母时,您会怎么做;-)

于 2013-04-11T09:12:33.907 回答
0

我认为您可能需要查看以下链接以供参考。它可能会帮助你..

如何在 SQL 中抑制或隐藏重复值?

于 2013-04-10T09:06:19.503 回答