我有下表。
CREATE TABLE IF NOT EXISTS `omc_schedule` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`trainer_id` int(11) NOT NULL,
`course` varchar(255) NOT NULL,
`capacity` int(11) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`parentid` int(10) NOT NULL,
`order` int(11) NOT NULL,
`booked` int(5) NOT NULL,
`type` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ...
我可以使用以下函数生成数组树。
function generateTree(&$tree, $parentid = 0) {
$this->db->select('*');
$this->db->where ('parentid',$parentid);
$this->db->where ('active','1');
$this->db->order_by('order asc, parentid asc');
$res = $this->db->get('omc_schedule');
if ($res->num_rows() > 0) {
foreach ($res->result_array() as $r) {
// push found result onto existing tree
$tree[$r['id']] = $r;
// create placeholder for children
$tree[$r['id']]['children'] = array();
// find any children of currently found child
$this->generateTree($tree[$r['id']]['children'],$r['id']);
}
}
$res->free_result();
return $tree;
}
现在我想加入培训师桌来获得培训师的名字。
CREATE TABLE IF NOT EXISTS `omc_trainer` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`trainer_name` varchar(50) NOT NULL,
`trainer_image` varchar(100) NOT NULL,
`video_url` text NOT NULL,
`desc` text NOT NULL,
PRIMARY KEY (`id`)
)
现在我尝试以不同的方式加入,但我无法在每个阵列中获得教练的名字。
有什么方法可以使用JOIN在递归函数中获取教练的名字?
上面的函数是CodeIgniter,但请忽略它。
提前致谢。
答案 0 :(得分:2)
我更喜欢对数据库进行一次调用并返回树/子树,因为它更有效并保持应用程序代码清洁。
以下是您可以查看您感兴趣的示例:
完整的脚本:http://paste.pocoo.org/show/274386/
-- TABLES
drop table if exists trainer;
create table trainer
(
trainer_id smallint unsigned not null auto_increment primary key,
name varchar(255) not null
)
engine=innodb;
drop table if exists schedule;
create table schedule
(
sched_id smallint unsigned not null auto_increment primary key,
trainer_id smallint unsigned null,
name varchar(255) not null,
parent_sched_id smallint unsigned null,
key schedule_parent_idx(parent_sched_id),
key schedule_trainer_idx(trainer_id)
)
engine=innodb;
-- STORED PROCEDURES
drop procedure if exists schedule_hier;
delimiter #
create procedure schedule_hier
(
in p_sched_id smallint unsigned
)
begin
declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;
create temporary table hier(
parent_sched_id smallint unsigned,
sched_id smallint unsigned,
depth smallint unsigned default 0
)engine = memory;
insert into hier select parent_sched_id, sched_id, v_depth from schedule where sched_id = p_sched_id;
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table tmp engine=memory select * from hier;
while not v_done do
if exists( select 1 from schedule p inner join hier on p.parent_sched_id = hier.sched_id and hier.depth = v_depth) then
insert into hier
select p.parent_sched_id, p.sched_id, v_depth + 1 from schedule p
inner join tmp on p.parent_sched_id = tmp.sched_id and tmp.depth = v_depth;
set v_depth = v_depth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = v_depth;
else
set v_done = 1;
end if;
end while;
select
s.sched_id,
s.name as schedule_name,
p.sched_id as parent_sched_id,
p.name as parent_schedule_name,
t.trainer_id,
t.name as trainer_name,
hier.depth
from
hier
inner join schedule s on hier.sched_id = s.sched_id
inner join schedule p on hier.parent_sched_id = p.sched_id
inner join trainer t on s.trainer_id = t.trainer_id
order by
hier.depth, hier.sched_id;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end #
delimiter ;
-- TEST DATA
insert into trainer (name) values ('trainer 1'),('trainer 2'),('trainer 3');
insert into schedule (name, trainer_id, parent_sched_id) values
('Schedules',null, null),
('Schedule 1',3,1),
('Schedule 2',2,1),
('Schedule 2-1',1,3),
('Schedule 2-2',3,3),
('Schedule 2-2-1',3,5),
('Schedule 2-2-2',2,5),
('Schedule 2-2-2-1',1,7);
-- TESTING
-- just call this stored procedure from your php
call schedule_hier(3);
sched_id schedule_name parent_sched_id parent_schedule_name trainer_id trainer_name depth
======== ============= =============== ==================== ========== ============ =====
3 Schedule 2 1 Schedules 2 trainer 2 0
4 Schedule 2-1 3 Schedule 2 1 trainer 1 1
5 Schedule 2-2 3 Schedule 2 3 trainer 3 1
6 Schedule 2-2-1 5 Schedule 2-2 3 trainer 3 2
7 Schedule 2-2-2 5 Schedule 2-2 2 trainer 2 2
8 Schedule 2-2-2-1 7 Schedule 2-2-2 1 trainer 1 3