简体   繁体   English

单个查询即可获取类别和文章

[英]Get categories and articles with a single query

I got two SQL-Tables: 我有两个SQL表:

  1. categories: id, title, level, parent 类别:ID,标题,级别,父级
  2. articles: id, title, category_id 文章:ID,标题,category_id

Now I want to get this result: 现在我想得到这个结果:

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

I would do it this way: 我会这样:

$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 />';
        }
    }

}

First of all, this is quite bad, as it just gets articles from the sub-categories (not for the categories) and there is just the selection of one level deep. 首先,这很不好,因为它只是从子类别(而不是类别)中获取文章,而且只能选择一个级别的内容。

Second: I'm using three querys, which are executed multiple times, just for that basic thing. 第二:我正在使用三个查询,这些查询多次执行,仅用于基本操作。 Performance... :-( 性能... :-(

I would like to solve that problem with just one SQL-query. 我只想用一个SQL查询来解决这个问题。 Is this possible? 这可能吗? (Then I would create the output...) (然后我将创建输出...)

SQLfiddle: http://sqlfiddle.com/#!2/2a4f2 SQLfiddle: http ://sqlfiddle.com/#!2/2a4f2

You could try this statement: 您可以尝试以下语句:

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

This gives you all articles including primary category and (optional) parent category. 这为您提供了所有文章,包括主要类别和(可选)父类别。 But you have to consider, that category can be the main or the sub category. 但您必须考虑,该类别可以是主类别或子类别。

You can change it that way to always get the main and sub category directly and sort for it. 您可以通过这种方式进行更改,以始终直接获取主类别和子类别并对其进行排序。

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

The IFNULL looks if there is a parent category. IFNULL查找是否有父类别。 If yes, the parent P is main category; 如果是,则父级P为主要类别;否则,为P if not, the category C is the main. 如果不是,则类别C是主要类别。 The next line checks is parent P is NULL . 下一行检查的是父级P是否为NULL If yes, there is no subcategory; 如果是,则没有子类别; if no, the Category C is the subcategory. 如果否,则类别C是子类别。 Looks a little unhandy, but for two levels it works fine: 看起来有点不方便,但在两个级别上都可以正常工作:

http://sqlfiddle.com/#!2/0ed4d/4 http://sqlfiddle.com/#!2/0ed4d/4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM