MySQL:为一个语句中的项目选择类别和(可选)子类别

时间:2014-11-20 16:30:21

标签: php mysql sql

在我的MySQL数据库中,我有两个表,一个用于项目,一个用于类别:

项目表看起来像这样:

 id | project_title        | category_id
 ---|----------------------|------------
  1 | My Book Project      | 101
  2 | My Comic Project     | 102
  3 | My Magazine Project  | 104

然后我有类别。这些可以有一个父类别,它存储在同一个表中:

 id | category_title     | parent_id  
 ---|--------------------|----------
101 | Books              | 0
102 | Comics             | 101
103 | DVDs               | 0
104 | Magazines          | 101

我想获取具有相应类别和(可选)子类别的所有项目(如果提供了parent_id)。如果类别没有子类别,则子类别应该类似于“ - ”或“无”。

现在我知道如何用几个语句来获取所有这些值:

第一声明:获取具有指定类别的项目(可以是主要类别或子类别,因此我也会获取类别的parent_id):

SELECT
    p.project_title, 
    c.category_title,
    c.parent_id as cat_parent_id
FROM
    projects p, 
    categories c
WHERE
    p.category_id = c.id

第二个声明:之后,我可以在循环中获取项目的可能子类别,或者将找到的类别指定为主要类别,例如用php:

<?php
foreach( $rows as $project ) {
    if ( $project['cat_parent_id'] > 0 ) {
        $project['sub_category'] = $project['category_title'];
        // query main-category here
    }
    else {
        $project['main_category'] = $project['category_title'];
        $project['sub_category'] = 'none';
    }

    // do things with this project ...
}
?>

问题是我会找到每个项目的另一个查询,这不太好。我认为应该有一种方法可以在一个语句中获取所有必需的值。我在SO上发现this question几乎相同,但在我的情况下,子类别是obtional。

正如John Cleese所说:有人可以帮我一把吗?

2 个答案:

答案 0 :(得分:4)

您可以两次加入类别:

SELECT
    p.project_title, 
    c.category_title,
    COALESCE(c0.category_title, '-') 
FROM projects p join categories c on p.category_id = c.id
                left join categories c0 on c.parent_id = c0.id;

但它只适用于两个级别的层次结构(任何类别可能只有零个或一个父级)。

根据评论:

SELECT
    p.project_title, 
    COALESCE(c0.category_title, c.category_title),
    case when c0.id is not null then c.category_title else '-' end
FROM projects p join categories c on p.category_id = c.id
                left join categories c0 on c.parent_id = c0.id;

答案 1 :(得分:0)

SELECT
    p.project_title, 
    IF(c2.category_title is null,
       c1.category_title,
       c2.category_title) as main_category,
    IF(c2.category_title is null,
       "none",
       c1.category_title) as sub_category
FROM projects p
LEFT JOIN categories c1 ON (c1.id = p.category_id)
LEFT JOIN categories c2 ON (c2.id = c1.parent_id)

http://sqlfiddle.com/#!2/85020/1

返回请求的结果:

PROJECT_TITLE        MAIN_CATEGORY  SUB_CATEGORY
My Book Project      Books          none
My Comic Project     Books          Comics
My Magazine Project  Books          Magazines