所以我在submissions_comments
架构中接受了Select Parent and Children With MySQL接受的答案,如下所示:
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(10) unsigned | NO | MUL | NULL | |
| submission_id | int(11) | NO | MUL | NULL | |
| comment | text | NO | | NULL | |
| parent_id | int(10) unsigned | YES | MUL | NULL | |
| created | datetime | NO | MUL | NULL | |
| created_ip | int(11) | NO | | NULL | |
| helpful_count | int(11) | NO | MUL | NULL | |
| deleted | tinyint(4) | NO | MUL | 0 | |
+---------------+------------------+------+-----+---------+----------------+'
作为
SELECT *
FROM submissions_comments AS parent
LEFT JOIN submissions_comments AS child
ON child.parent_id = parent.id
WHERE parent.parent_id IS NULL
ORDER BY parent.id, child.id;
我最终得到了以下结果:
+----+---------+---------------+-------------------------------+-----------+---------------------+------------+---------------+---------+------+---------+---------------+--------------------------------+-----------+---------------------+------------+---------------+---------+
| id | user_id | submission_id | comment | parent_id | created | created_ip | helpful_count | deleted | id | user_id | submission_id | comment | parent_id | created | created_ip | helpful_count | deleted |
+----+---------+---------------+-------------------------------+-----------+---------------------+------------+---------------+---------+------+---------+---------------+--------------------------------+-----------+---------------------+------------+---------------+---------+
| 1 | 15 | 23 | This is a parent | NULL | 2014-02-19 01:41:39 | 127001 | 0 | 0 | 2 | 15 | 23 | This is a child comment | 1 | 2014-02-19 01:41:43 | 127001 | 0 | 0 |
| 1 | 15 | 23 | This is a parent | NULL | 2014-02-19 01:41:39 | 127001 | 0 | 0 | 4 | 15 | 23 | This is a second child comment | 1 | 2014-02-19 02:01:29 | 127001 | 0 | 0 |
| 3 | 15 | 23 | I don't have any children | NULL | 2014-02-19 01:43:30 | 127001 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+----+---------+---------------+-------------------------------+-----------+---------------------+------------+---------------+---------+------+---------+---------------+--------------------------------+-----------+---------------------+------------+---------------+---------+
如您所见,结果中的前两行包含已加入子注释的父注释。有没有办法让MySQL在返回的一个父注释中干净地嵌套所有子注释,或者我是否需要在返回的结果对象上使用下划线的_.pluck
方法?
答案 0 :(得分:3)
这是你的意思吗?
SELECT parent.id, MAX(parent.comment) as pcomm,
GROUP_CONCAT(child.id ORDER BY child.id) as siblings,
GROUP_CONCAT(child.comment ORDER BY child.id) as siblingComments
FROM submissions_comments AS parent
LEFT JOIN submissions_comments AS child
ON child.parent_id = parent.id
WHERE parent.parent_id IS NULL
GROUP BY parent.id
ORDER BY parent.id;
我假设通过“嵌套”你只是意味着你希望兄弟姐妹的结果以某种方式组合在一起。
答案 1 :(得分:1)
编辑 - 试试看你是否喜欢它,否则跳到另一个group_concat想法 -
以下方法将仅在存在子注释(或无)的第一行显示每个父级的所有列值。在显示第2,第3等子注释的行上,父项的值都将为空,并且只有兄弟数据将显示在右侧。这使您可以快速了解一个注释(父)的结束位置以及另一个注释(另一个兄弟节点序列)的开始位置。
SELECT case when parent.id = child_min_id then parent.id else null end as id,
case when parent.id = child_min_id then child.parent.user_id else null end as user_id,
case when parent.id = child_min_id then parent.submission_id else null end as submission_id,
case when parent.id = child_min_id then parent.comment else null end as comment,
case when parent.id = child_min_id then parent.parent_id else null end as parent_id,
case when parent.id = child_min_id then parent.created else null end as created,
case when parent.id = child_min_id then parent.created_ip else null end as created_ip,
case when parent.id = child_min_id then parent.helpful_count else null end as helpful_count,
case when parent.id = child_min_id then parent.deleted else null end as deleted,
child.*
FROM submissions_comments AS parent
LEFT JOIN submissions_comments AS child
ON child.parent_id = parent.id
left join submissions_comments as child_min
on child.id = child_min.id
WHERE parent.parent_id IS NULL
and (child_min.id =
(select min(x.id)
from submissions_comments x
where x.parent_id = child.parent_id) or child_min.id is null)
ORDER BY parent.id, child.id;
以下是对上述内容的编辑,以回答如何为父/子两者加入用户表,以及如何显示每个子列的相关列。请注意,因为我不确定您要选择哪些列,所以我只为父/子(在您的版本中更改)抓取了一个名为“relatedcolumn”的列:
SELECT case when parent.id = child_min_id then parent.id else null end as id,
case when parent.id = child_min_id then child.parent.user_id else null end as user_id,
case when parent.id = child_min_id then parent.submission_id else null end as submission_id,
case when parent.id = child_min_id then parent.comment else null end as comment,
case when parent.id = child_min_id then parent.parent_id else null end as parent_id,
case when parent.id = child_min_id then parent.created else null end as created,
case when parent.id = child_min_id then parent.created_ip else null end as created_ip,
case when parent.id = child_min_id then parent.helpful_count else null end as helpful_count,
case when parent.id = child_min_id then parent.deleted else null end as deleted,
case when u_par.id = child_min_id then u_par.relevant_column else null end as usertblcolumn,
child.*,
u.relevantcolumn as usertblcolumnforchild
FROM submissions_comments AS parent
LEFT JOIN submissions_comments AS child
ON child.parent_id = parent.id
left join submissions_comments as child_min
on child.id = child_min.id
left join users as u
on child.id = u.id
left join users as u_par
on parent.id = u_par.id
WHERE parent.parent_id IS NULL
and (child_min.id =
(select min(x.id)
from submissions_comments x
where x.parent_id = child.parent_id) or child_min.id is null)
ORDER BY parent.id, child.id;
小组联合方法:
关于想要元数据的评论,您可以同时使用group_concat和concat同时垂直和水平聚合,如下所示:
SELECT parent.id,
MAX(parent.comment) as pcomm,
GROUP_CONCAT(concat(child.id,', ',child.user_id,', ',child.created,', ',child.comment) ORDER BY child.id) as siblings
FROM submissions_comments AS parent
LEFT JOIN submissions_comments AS child
ON child.parent_id = parent.id
WHERE parent.parent_id IS NULL
GROUP BY parent.id
ORDER BY parent.id;
如果你想要的话,你仍然需要将它们分成不同的列,但其他字段将并排存在。
如果它更容易阅读,你也可以使用文字来区分:
SELECT parent.id,
MAX(parent.comment) as pcomm,
GROUP_CONCAT(concat('Child ID ',
', ',
child.id,
', ',
'Child User ID ',
', ',
child.user_id,
', ',
'Child Date ',
', ',
child.created,
', ',
'Child Comment ',
child.comment) ORDER BY child.id) as siblings
FROM submissions_comments AS parent
LEFT JOIN submissions_comments AS child
ON child.parent_id = parent.id
WHERE parent.parent_id IS NULL
GROUP BY parent.id
ORDER BY parent.id;
答案 2 :(得分:0)
我没有完全说出来,我认为你得到的这类问题如下:
<强> Ordered_Item 强>
ID | Item_Name
1 | Pizza
2 | Stromboli
<强> Ordered_Options 强>
Ordered_Item_ID | Option_Number | Value
1 43 Pepperoni
1 44 Extra Cheese
2 44 Extra Cheese
<强>输出强>
ID | Item_Name | Option_1 | Option_2
1 Pizza Pepperoni Extra Cheese
2 Stromboli NULL Extra Cheese
我使用此方法的建议可解决此问题,如下所示:
最简单的方法是在这里使用 GROUP_CONCAT组功能..
选择 ordered_item.id为
Id
, ordered_item.Item_Name为ItemName
,GROUP_CONCAT(Ordered_Options.Value)为
来自ordered_item,ordered_options 的Options
其中ordered_item.id = ordered_options.ordered_item_id
按ordered_item.id分组
哪个会输出:
Id ItemName Options
1 Pizza Pepperoni,Extra Cheese
2 Stromboli Extra Cheese
这样您就可以拥有任意数量的选项而无需修改查询。
啊,如果您看到结果被裁剪,您可以像这样增加GROUP_CONCAT的大小限制:
SET SESSION group_concat_max_len = 8192;
答案 3 :(得分:0)
如果要在父行的一列中显示所有子注释,则需要使用函数对其进行存档。
以下是一个例子:
CREATE DEFINER = 'root'@'localhost' FUNCTION `getChildComments`(p_parent_id INTEGER(11))
RETURNS varchar(4000)
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
begin
declare v_comments, v_return varchar(4000);
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR
select comment
from submissions_comments t
where parent_id=p_parent_id;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
set v_return='';
OPEN cur1;
REPEAT
FETCH cur1 INTO v_comments;
IF NOT done THEN
if (v_return='') then
set v_return=v_comments;
else
set v_return=concat(v_return,';',v_comments);
end if;
end if;
UNTIL done END REPEAT;
CLOSE cur1;
return v_return;
end;
然后:
SELECT parent_id, getChildComments(parent_id) from (
SELECT distinct parent_id as prarent_id from submissions_comments ) x ;
确保在parent_id列上有索引;)
P.S。:我在上面的函数中使用VARCHAR
,但我认为它也适用于TEXT
。