我有两个SQL表:
现在我想得到这个结果:
Category 1
Article 1
Artcile 2
Article 3
Category 2
Subcategory 1
Article 1
Artcile 2
Article 3
Subcategory 2
Article 1
Artcile 2
Article 3
Category 3
Article 1
Artcile 2
Article 3
我会这样做:
$categories = $db->prepare('SELECT * FROM categories WHERE level = 0');
$categories->execute();
while($category = $categories->fetch(PDO::FETCH_OBJ)) {
$sub_categories = $db->prepare('SELECT * FROM categories WHERE parent = :parent_id');
$sub_categories->bindParam(':parent_id', $category->id, PDO::PARAM_INT);
$sub_categories->execute();
while($sub_category = $sub_categories->fetch(PDO::FETCH_OBJ)) {
$articles = $db->prepare('SELECT * FROM articles WHERE category_id = :category_id');
$articles->bindParam(':category_id', $sub_category->id, PDO::PARAM_INT);
$articles->execute();
while($article = $articles->fetch(PDO::FETCH_OBJ)) {
echo $article->title.'<br />';
}
}
}
首先,这是非常糟糕的,因为它只是从子类别(不是类别)获取文章,只有一个级别的选择。
第二:我使用三个查询,这些查询被多次执行,只是为了那个基本的东西。表现......: - (
我想用一个SQL查询来解决这个问题。这可能吗? (然后我会创建输出......)
SQLfiddle: http://sqlfiddle.com/#!2/2a4f2
答案 0 :(得分:0)
你可以试试这句话:
SELECT
A.id, A.title,
C.id AS category_id, C.title AS category_title, C.level AS category_level,
P.id AS parent_id, P.title AS parent_title, P.level AS parent_level
FROM articles AS A
INNER JOIN categories AS C ON A.category_id=C.id
LEFT JOIN categories AS P ON C.parent=P.id
这将为您提供所有文章,包括主要类别和(可选)父类别。但您必须考虑,该类别可以是主要类别或子类别。
您可以通过这种方式更改它,以便始终直接获取主要和子类别并对其进行排序。
SELECT
IFNULL(P.id, C.id) AS category_id, IFNULL(P.title, C.title) AS category_title,
IF(P.id IS NULL, NULL, C.id) AS subcategory_id, IF(P.title IS NULL, NULL, C.title) AS subcategory_title,
A.id, A.title
FROM articles AS A
INNER JOIN categories AS C ON A.category_id=C.id
LEFT JOIN categories AS P ON C.parent=P.id
ORDER BY category_id, subcategory_id, A.id
IFNULL
查看是否存在父类别。如果是,则父P
是主要类别;如果没有,则类别C
是主要的。下一行检查是父P
是NULL
。如果是,则没有子类别;如果不是,则类别C
是子类别。看起来有点不方便,但是对于两个级别它可以正常工作: