我想输出类别名称、每个类别中的子类别名称以及每个类别和子类别中的文章。
输出应该在<ul>和内部<ul>标记中。
下面是输出应该是什么样子:

我有以下5个表:
table_article_categories(articlecat_id, parent_id, articlecat_status, ...)
table_article_to_article_categories(articlecat_id, articles_id)
table_articles(articles_id, articles_status, ...)
table_articles_description(articles_id, language_id, articles_heading_title, ...)
table_article_categories_description(articlecat_id, articlecat_name, language_id, ...)到目前为止,我已经实现了这个SQL:
SELECT
ac.parent_id,
ac.articlecat_id,
a.articles_id,
ad.articles_heading_title AS article_name,
acd.articlecat_name
FROM
table_article_categories AS ac
LEFT JOIN
table_article_to_article_categories AS atac
ON
atac.articlecat_id = ac.articlecat_id
LEFT JOIN
table_articles AS a
ON
a.articles_id = atac.articles_id
AND
a.articles_status = 1
LEFT JOIN
table_articles_description AS ad
ON
ad.articles_id = a.articles_id
AND
ad.language_id = 1
INNER JOIN
table_article_categories_description AS acd
ON
acd.articlecat_id = ac.articlecat_id
AND
acd.language_id = 1
WHERE
ac.parent_id = 99 # --- This is the root article-categori-id ---
AND
ac.articlecat_status = 1
AND
ac.articlecat_id != 77 # --- This is an excluded article-categori-id ---
ORDER BY
acd.articlecat_name ASC,
article_name ASC发布于 2021-11-09 23:59:12
当我查看您想要的输出时,我看到的是一棵树,它的叶子可能链接到文章,也可能不链接到文章。没有附加文章的叶子可以被认为是一个类别。有文章的叶子可以被认为是文章。
有了这个假设,您就可以构建您的模式:
Category_Tree Category Article
------------ -------- -------
id id id
pid category_id article_id
article_id language_id language_id
category_id title title(当然,这不是第四范式。如果需要,您可以进行标准化,但现在还为时过早。)
现在,应该更容易看到如何解决您的问题了:您所要做的就是首先在php数组中构建树;然后迭代该数组并分别查询每个叶的详细信息(或者至少查询您的链接的href和text所需的信息)。
一个简单的递归入门:
<?php
/*
Category_Tree
id pid name article_id category_id
1 0 Category 1 ... ...
2 1 Article 1
3 0 Category 2
4 3 SubCategory 1
5 4 Article 7
6 4 Article 8
7 3 Article 2
8 3 Article 3
9 0 Category 3
10 9 Article 4
11 9 Article 5
12 0 Article 6
*/
function getRecord($pid) : array
{
// database access is left to the reader
// $db->run('SELECT * FROM CATEGORY_TREE WHERE PID=?',[$pid]);
// $rows = [];
// while($row = $db->getRow()) {
// $rows[] = $row;
// }
return $rows;
}
function makeTree($pid) : array
{
static $idList = [];
static $indent = 0;
$rows = getRecord($pid);
foreach ($rows as $row) {
$idList[] = [
'id' => $row->id,
'indent' => $indent,
'articleId' => $row->articleId,
'categoryId' => $row->categoryId,
];
$indent++;
makeTree($row->id);
$indent--;
}
return $idList;
}
$idList = makeTree(0);*警告:这不能直接转换为无序列表。我不喜欢将html和逻辑混合在一起,但在这种情况下,您需要在递归中构建一个字符串。这是一个更有针对性的问题,你可以问或研究。
现在,遍历$idList并查找所需的信息来填充所需的标题
psuedocode (数据库检索再次留给读者):
// $languageId is already assigned as you see fit
// add title to $idList
foreach($idList as $index => $row) {
if($row->articleId ?? FALSE) {
$db->run('SELECT TITLE FROM ARTICLE WHERE ARTICLE_ID=? AND LANGUAGE_ID=?', [$row->articleId, $languageID]);
} else {
$db->run('SELECT TITLE FROM CATEGORY WHERE CATEGORY_ID=? AND LANGUAGE_ID=?', [$row->categoryId, $languageId]);
}
$row->title = $db->get('title');
$idList[$index] = $row;
}然后,当您输出html时,您只需再次迭代$idList并根据需要输入值。
显然,这不是一个剪切粘贴的答案;有太多的编码工作要做。但希望这能将您引向一个可行的方向。
发布于 2021-11-09 23:43:14
而不是在单个查询中完成,我建议在单独的多个查询上循环的解决方案。
对于您的情况,只需要3个单独的查询,因为您有3层(Cat/Subcat/文章)。另一方面,由于层数已经定义(并且是有限的),所以这次不需要使用递归(如果有无限的(或未知的)层级,我们需要递归)。
请将数据库模式更改为正确且定义明确的模式(如下所示):
category (catid, name)
subcategory (subcatid, catid, name)
article (articleid, catid, subcatid, name)其中catid is linking to category;和subcatid is linking to subcategory,(如果适用)
所以数据将是(参考你帖子中的图片)
category (catid, name)
1 Category1
2 Category2
3 Category3
subcategory (subcatid, catid, name)
1 2 Subcategory1
article (articleid, catid, subcatid, name)
1 0 0 Article6
2 1 0 Article1
3 2 1 Article7
4 2 1 Article8
5 2 0 Article2
6 2 0 Article3
7 3 0 Article4
8 3 0 Article5我认为在上面的模式中优势和清晰度是显而易见的,所以我不认为需要进一步的解释。当然,您还可以向表中添加更多的数据字段,但主要结构如上所述。
现在,请使用PHP生成以下HTML:
对于第一个ul,li (只运行一次)
(a)循环遍历类别并显示名称
然后
(b)循环遍历具有(catid=0或catid为null)和(subcatid=0或subcatid为null)的文章展示记录,然后显示名称
第2个ul,li
对于上面(a)中记录的每个:
(c)循环遍历作为catid=category.catid的子类别并显示子类别名称
然后
(d)循环遍历项目,显示具有catid=category.catid和(subcatid=0或subcatid为null)的记录,然后显示名称
第3个ul,li
对于上述(c)中记录的每个:
(e)循环遍历文章,显示具有catid=category.catid和subcatid=subcategory.subcatid的记录,然后显示名称
为了演示,我将把“第2个ul,li”作为一个称为branch2()的函数,将“第3个ul,li”作为一个称为branch3()的函数,然后相应地调用它们。
因此,代码将是:
<?php
$servername = "localhost";
$username = "xxxxxxx";
$password = "xxxxxxxxxx";
$dbname = "xxxxxx";
$conn = new mysqli($servername, $username, $password, $dbname);
$sql1="(
SELECT name, catid AS id1, '1' as subdata
FROM category
ORDER BY id1
)
UNION (
SELECT name, articleid AS id1, '0' as subdata
FROM article
WHERE catid =0
AND subcatid =0
ORDER BY id1
)";
$result = $conn -> query($sql1);
$index=0;
$count=mysqli_num_rows($result);
echo "<ul>";
while ($index <$count) {
$row = $result -> fetch_assoc() ;
echo "<li>". $row["name"];
if ($row["subdata"]=='1'){
branch2($row["id1"], $conn);
}
$index++;
}
echo "</ul>";
$result -> free_result();
function branch2($var1, $conn){
$sql2="(
SELECT name, catid AS id1, subcatid as id2, 1 as subdata
FROM subcategory where catid=". $var1 . " ORDER BY id1 )
UNION (
SELECT name, articleid AS id1, 0 as id2 , 0 as subdata
FROM article
WHERE catid =" . $var1 . " AND subcatid =0 ORDER BY id1 )";
$result2 = $conn -> query($sql2);
$index2=0;
$count2=mysqli_num_rows($result2);
echo "<ul>";
while ($index2 <$count2) {
$row2 = $result2 -> fetch_assoc() ;
echo "<li>". $row2["name"];
if ($row2["subdata"]=='1') {
branch3($row2["id1"], $row2["id2"], $conn);
}
$index2++;
}
echo "</ul>";
$result2 -> free_result();
}
function branch3($var1, $var2, $conn){
$sql3="(
SELECT name, articleid AS id1, 0 as id2 , 0 as subdata
FROM article
WHERE catid =" . $var1 . " and subcatid=". $var2 . " ORDER BY id1 )";
$result3 = $conn -> query($sql3);
$index3=0;
$count3=mysqli_num_rows($result3);
echo "<ul>";
while ($index3 <$count3) {
$row3 = $result3 -> fetch_assoc() ;
echo "<li>". $row3["name"];
$index3++;
}
echo "</ul>";
$result3 -> free_result();
}
?>完整的工作示例可以在这里看到:
http://www.createchhk.com/SO/testso10Nov2021.php

https://stackoverflow.com/questions/69905591
复制相似问题