Php 如何获取以多行值连接的id记录
下面是我的桌子Php 如何获取以多行值连接的id记录,php,mysql,sql,wordpress,recursive-query,Php,Mysql,Sql,Wordpress,Recursive Query,下面是我的桌子 Id User_id type content item_id secondary_item_id 879 1 activity_comment Amazing 833 833 907 168 activity_comment Great 833 879 908 1
Id User_id type content item_id secondary_item_id
879 1 activity_comment Amazing 833 833
907 168 activity_comment Great 833 879
908 1 activity_comment Welcome 833 907
我想输出一个评论回复结构,可以用一个例子来描述。在上表中,您可以看到用户_id 1在833上发表评论这是一个帖子id a post,然后用户168回复他,然后再次用户1回复用户168
所以它可能像
**MY POST** ( This is a post )
---- First comment( Amazing)
------- replay comment (Great)
------------ sub replay (Welcome )
我已经编写了以下查询,但无法获得预期的输出
SQL查询:
<?php
$listReplay =$wpdb->get_results("(SELECT * FROM table_one WHERE id = ".$value['secondary_item_id']." AND type ='activity_comment') UNION DISTINCT
(SELECT * FROM table_one WHERE secondary_item_id = ".$value['secondary_item_id']." AND type ='activity_comment')");
?>
让我们首先了解如何加载原始数据:
select Id, content, item_id, secondary_item_id
from table_one
where item_id = 833
order by item_id, secondary_item_id;
上面的查询加载833帖子上的评论,并根据帖子id和父评论id对它们进行排序。到目前为止,一切正常。现在,假设原始数据存储在$rawResults中,则可以执行以下操作:
$map = [];
$parsedResults = [];
foreach ($rawResults as $rawResult) {
if ($rawResult["secondary_item_id"] === $rawResult["item_id"]) {
$parsedResults[$rawResult["Id"]] = [
"content" => $rawResult["content"],
"children" => []
];
$map[$rawResult["Id"]] = $parsedResults[$rawResults["Id"]];
} else {
$map[$rawResult["secondary_item_id"]]["children"][$rawResult["Id"]]= [
"content" => $rawResult["content"],
"children" => []
]
}
}
现在,您有了一个元素层次结构,主要级别是主注释,您可以在子项中找到答案。现在可以像下面这样遍历分层数组
function getComments($parsedResults, $prefix = "--- ") {
$output = "";
foreach ($parsedResults as $parsedResult) {
$output .= $prefix.$parsedResult["content"]."\n";
if (count($parsedResult["children"])) $output .= getComments($parsedResult["children"], "---".$prefix);
}
return $output;
}
如果您运行的是MySQL 8.0,典型的方法是使用递归查询遍历分层数据结构。这将通过单个查询生成所需的结果,因此这比在php中进行迭代要高效得多
with recursive cte as (
select t.*, 1 lvl
from mytable t
where
type ='activity_comment'
and item_id = 833
and secondary_item_id = item_id
union all
select t.*, c.lvl + 1
from mytable t
inner join cte c on c.id = t.secondary_item_id
where t.type = 'activity_comment'
)
select * from cte order by lvl
递归查询的锚点选择文章的第一条注释,即我们用条件secondary\u item\u id=item\u id标识的注释。然后,递归部分只遵循关系,直到它们耗尽
这将为您提供一个平面结构,列出所有评论的帖子,并添加一个名为lvl的列,指示每个元素的深度。您可以使用该信息处理应用程序中的显示
:
您可以使用下面的代码来获取SQL中的输出
WITH comment_activity(Id, User_id, type, content, post_id, secondary_item_id)
AS
(Select 879 , 1 , 'activity_comment' , 'Amazing' , 833 , 833 UNION
Select 907 , 168 , 'activity_comment' , 'Great' , 833 , 879 UNION
Select 908 , 1 , 'activity_comment' , 'Welcome' , 833 , 907
)
Select post_id as post,
ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY ID) as RN,
content as comment,
User_id,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY ID) = 1
THEN 'First_Comment (' + content + ')'
ELSE 'Reply_' + CONVERT(VARCHAR(20),ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY ID) - 1) + '( ' + content + ')'
END as Thread
from comment_activity
WHERE type = 'activity_comment'
AND post_id = 833
实际上,Lajos Arpad的解决方案可以在db中进行一些更改。 添加另一列parent\u item\u id。它基本上是该注释链的第一条注释。在您的示例中,所有3行的值都是879 现在这可以用了
select * from <table name>
where item_id = <item_id>
group by parent_item_id
order by secondary_item_id asc
您有item_id和secondary_item_id。我建议将其更新为父线程或正在讨论的主线程,以及回复到的注释。最后,添加一个时间戳,它使排序变得更好。至于SQL,我会把它推到更容易编码的地方,只需要获取数据。对于层次数据,最好使用嵌套集模型。请参见“未获取结果”,它显示了我在问题中提到的项目\u id 833未获取结果的所有注释,结果必须在层次结构注释结构中。@SamirSheikh:SQL查询按设计返回平面结构行不能嵌套。此查询按从根到子节点的正确顺序提供注释,并有一列指示每个节点的深度。这是SQL查询所能达到的最佳效果。从这些结果开始,很容易使用php循环并使用lvl列在应用程序中将行显示为层次结构。同样,请记住,使用一个查询比在php中迭代并运行多个查询要高效得多。@PaulSpiegel:我明白你的意思。根据OP的需求,有一些解决方案。例如,我们可以跟踪每个注释的路径,并使用if进行排序。但是OP的示例数据并没有显示这个用例,所以我并没有实现它。
select * from <table name>
where item_id = <item_id>
group by parent_item_id
order by secondary_item_id asc