PHP,MYSQL嵌套查询

时间:2013-07-30 12:32:17

标签: php mysql

我使用php和Mysql来查询数据库。我想要做的是创建以下内容:

Project Name 1
List todo
List todo
List todo 

Project Name 2
List todo
List todo
List todo 

我有以下mysql表:

Project
project.projectId
project.projectName

Todo
todo.todoId
todo.todoEntry
todo.todoProjectid

我可以查询表并浏览整个项目列表,然后加入todo。但是,我想创建一个标题(项目名称),然后在下面进行循环。

我可以根据父级对每个待办事项执行嵌套的sql查询,但这对我来说听起来不够高效。有人建议改进吗?

2 个答案:

答案 0 :(得分:1)

我让戈登的查询更简单一些。它现在完全符合您的要求。

SELECT
    `name`
FROM 
    (
        (SELECT 'project' as `type`, `name`, `id` as `projectid` FROM `Project`)
        UNION ALL
        (SELECT 'todo' as `type`, `name`, `projectid` FROM `Todo`)
    ) as `combined`
ORDER BY
    `project_id`, `type`

结果:

Outcome http://cl.ly/QXaG/Schermafbeelding%202013-07-30%20om%2014.58.46.png


PHP只获取所有行的列表:

$q = $db->query("SELECT `name` FROM ((SELECT 'project' as `type`, `name`, `id` as `project_id` FROM `projects`) union all (SELECT 'todo' as `type`, `name`, `project_id` FROM `todos`)) as `combined` ORDER BY `project_id`, `type`");

while($row = $q->fetch_object()) {
    echo $row->name . '<br />';
}

PHP使用'复杂'查询获取嵌套列表:

$q = $db->query("SELECT `name`, `type` FROM ((SELECT 'project' as `type`, `name`, `id` as `project_id` FROM `projects`) union all (SELECT 'todo' as `type`, `name`, `project_id` FROM `todos`)) as `combined` ORDER BY `project_id`, `type`");

echo '<ul>';

$needToBeClosed = false;

while($row = $q->fetch_object()) {
    if($row->type == 'project' AND $needToBeClosed) {
        echo '</ul></li>';
        $needToBeClosed = false;
    }

    echo '<li>' . $row->name;

    if($row->type == 'project') {
        echo '<ul>';
        $needToBeClosed = true;
    } else {
        echo '</li>';
    }
}

if($needToBeClosed) {
    echo '</ul></li>';
}

echo '</ul>';

但是正如您所看到的,您在查询中尝试的次数越多。 PHP需要以更简单的方式使用它。因此,您需要在SQL和PHP之间找到平衡,以获得最好的代码。我通常不会采用上述方法,但只需执行以下多个查询:

PHP获取没有“复杂”查询的嵌套列表:

$projects = $db->query('SELECT * FROM `projects`');

echo '<ul>';

while($project = $projects->fetch_object()) {
    echo '<li>' . $project->name . '<ul>';
    $todos = $db->query('SELECT * FROM `todos` WHERE `project_id` = ' . $project->id);

    while($todo = $todos->fetch_object()) {
        echo '<li>' . $todo->name . '</li>';
    }

    echo '</ul></li>';
}

echo '</ul>';

您仍然需要根据自己的需要修改查询(表名等)。

答案 1 :(得分:0)

在这种情况下,您从查询中获得相同的列。有些来自Project,有些来自Todo。挑战在于以正确的方式订购它们:

select which, name
from ((select 'Project' as which, name, 1 as ordering, projectid, NULL as id
       from  Project p
      ) union all
      (select 'List' as which, entry, 2 as ordering, projectid, id
       from Todo t
      )
     ) t
order by projectid,
         ordering,
         id;