我有两张桌子:
1。文章:
id, title, content, catid
2。类:
id, title, parent
现在我想在一个框中显示所有类别。这些框应包含所有子类别(= parent)作为框和所有文章(= catid)
e.g。
Box Vegetables (Level 1)
Box Red vegetables (Level 2)
Tomatoes
Beetroot
Box Green vegetables (Level 2)
Cucumber
Other vegetable 1 (article)
Other vegetable 2 (article)
Box Cars (Level 1)
BoxRacing Cars (Level 2)
F1 Racing Car
Nascar Car
Ford Fiesta (article)
Opel Corsa (article)
这是我的SQL和PHP尝试。
$categories = $db->prepare('SELECT id, title FROM categories');
$subcategories = $db->prepare('SELECT id, title FROM categories WHERE parent = :id');
$articles = $db->prepare('SELECT id, title, content FROM articles WHERE catid = :id');
$categories->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
$categories->execute();
if ($categories->rowCount()) {
while($cat = $categories->fetch(PDO::FETCH_OBJ)) {
echo '<div class="list">';
echo cat->title;
$subcategories->bindParam(':id', $cat->id, PDO::PARAM_INT);
$subcategories->execute();
if ($subcategories->rowCount()) {
while($subcat = $subcategories->fetch(PDO::FETCH_OBJ)) {
echo '<div class="list">';
echo subcat->title;
$art->bindParam(':id', $subcat->id, PDO::PARAM_INT);
$art->execute();
if ($art->rowCount()) {
while($article = $art->fetch(PDO::FETCH_OBJ)) {
echo $article->title;
}
}
echo '</div>';
}
}
$art->bindParam(':id', $cat->id, PDO::PARAM_INT);
$art->execute();
if ($art->rowCount()) {
while($article = $art->fetch(PDO::FETCH_OBJ)) {
echo $article->title;
}
}
echo '</div>';
}
}
我能更有效率吗?我真的需要那么多SQL语句和while循环吗?
答案 0 :(得分:0)
代码未经测试,请参阅注释:
//You're fetching everything anyway, so why not do it in a single step?
$categories = $db->prepare('SELECT id, title, parent FROM categories');
$articles = $db->prepare('SELECT id, title, content, catid FROM articles');
$categories->execute();
$articles->execute();
//Now we've got a mess, let's organize it
$categoriesById = array();
$childrenCategories = array();
$articlesByCategory = array();
while($cat = $categories->fetch(PDO::FETCH_OBJ)) {
$categoriesById[$cat->id] = $cat;
if ($cat->parent) $childrenCategories[$cat->parent] = $cat;
}
while($article = $articles->fetch(PDO::FETCH_OBJ)) {
$articlesByCategory[$article->catid][] = $article;
}
//A function for printing the categories, so that we can call it recursively
function printCategory($category, $childrenCategories, $articlesByCategory) {
echo '<div class="list">';
echo $category->title;
foreach($childrenCategories as $childrenCategory) {
printCategory($childrenCategory, array(), $articlesByCategory);
}
if (!empty($articlesByCategory[$category->id])) {
$article = $articlesByCategory[$category->id];
echo $article->title;
}
echo '</div>';
}
//Print out stuff
foreach($categoriesById as $id => $category) {
if ($category->parent) continue; //Skip subcategories
printCategory(
$category,
!empty($childrenCategories[$id]) ? $childrenCategories[$id] : array(),
$articlesByCategory
);
}
答案 1 :(得分:0)
我的观点是在数据库中形成数据。
首先,我认为没有articles
的{{1}}不能在描述的系统中。得出这样的结论后,我创建了一个查询来获取具有条件的数据,并实现了两个附加条件:
这是一个怪异的查询,用于在一个地方捕获所有描述的数据:
category
您可以在这里找到example of using this query
使用此查询在数据库中保存VIEW并将其用作PHP中的表。
例如,让我们将此查询命名为VIEW select article_id, article_title, article_content, article_catid, catid, subcatid, category, subcategory
from
(select articles.id as article_id, articles.title as article_title, articles.content as article_content, articles.catid as article_catid, cats_n_subs.catid, null as subcatid, cats_n_subs.category, null as subcategory
from
(select categories.id as catid,subcategories.id as subcatid, categories.title as category, subcategories.title as subcategory
from
(select * from
categories
where parent is null) as categories
left join
(select id, title, parent from categories
where parent is not null
union all
select null, null, null) as subcategories
on subcategories.parent = categories.id or subcategories.id is null
group by categories.id, subcategories.id, categories.title, subcategories.title
) as cats_n_subs
left join
articles
on
articles.catid = cats_n_subs.catid
group by articles.id, articles.title, articles.content, articles.catid, cats_n_subs.catid,cats_n_subs.category
union all
select articles.id as article_id, articles.title as article_title, articles.content as article_content, articles.catid as article_catid, cats_n_subs.catid, cats_n_subs.subcatid as subcatid, cats_n_subs.category, cats_n_subs.subcategory as subcategory
from
(select categories.id as catid,subcategories.id as subcatid, categories.title as category, subcategories.title as subcategory
from
(select * from
categories
where parent is null) as categories
left join
categories as subcategories
on subcategories.parent = categories.id
) as cats_n_subs
left join
articles
on
articles.catid = cats_n_subs.subcatid
where articles.id is not null) as cats_n_arts
order by category, case when subcategory is null then 1 else 0 end, subcategory;
。
下一步是在PHP中准备和使用数据:
cats_n_arts
不幸的是,我没有可能测试这段代码,但它应该可以正常工作。