我使用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查询,但这对我来说听起来不够高效。有人建议改进吗?
答案 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;