使用SQL和PHP从不同的引用表中获取层次结构树
我有多个具有类似基本结构的表:使用SQL和PHP从不同的引用表中获取层次结构树,php,sql,treeview,hierarchical,Php,Sql,Treeview,Hierarchical,我有多个具有类似基本结构的表: biopsy_p0 id | biopsy_id | introduced biopsy_p1 id | biopsy_p0_id | introduced biopsy_p2 id | biopsy_p1_id | introduced 我的目标是获得依赖关系的树视图 活检\u p0.id->活检\u p1.活检\u p0\u id->活检\u p2.活检\u p1\u id 我试着只使用SQL,但从我的问题中可以看出,我在这方面不是很有经验。到目前
biopsy_p0
id | biopsy_id | introduced
biopsy_p1
id | biopsy_p0_id | introduced
biopsy_p2
id | biopsy_p1_id | introduced
我的目标是获得依赖关系的树视图
活检\u p0.id->活检\u p1.活检\u p0\u id->活检\u p2.活检\u p1\u id
我试着只使用SQL,但从我的问题中可以看出,我在这方面不是很有经验。到目前为止,我所能找到的一切都是关于层次树的参考文献。但它们总是只使用一个带有内部引用的表
--更新:
我现在用PHP实现了它,这真的不是一个好的解决方案,我希望我能用SQL实现它,以便更好地扩展:
PHP代码:
SQL数据:
也许最好有一个层次关系表,通过ID引用另一个存储实际数据的表。。。因此,我只涉及两个表,如果添加新元素,将更加灵活…让我们从声明键开始:
CREATE TABLE IF NOT EXISTS `biopsy` (
`id` int(11) unsigned NOT NULL primary key,
`creation_date` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;
INSERT INTO `biopsy` (`id`, `creation_date`) VALUES
(226, '2015-03-08'),
(227, '2015-03-08');
CREATE TABLE IF NOT EXISTS `biopsy_p0` (
`id` int(11) unsigned NOT NULL primary key,
`biopsy_id` int(11) unsigned NOT NULL,
`introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
alter table biopsy_p0 add constraint fk_biopsy
foreign key (biopsy_id)
references biopsy (id)
on update cascade
on delete cascade;
INSERT INTO `biopsy_p0` (`id`, `biopsy_id`, `introduced`) VALUES
(1, 226, '2014-12-31'),
(2, 226, '2014-12-31'),
(3, 226, '2014-12-31'),
(4, 227, '2015-03-14');
-- violates the f.k. introduced
-- (5, 255, '2015-03-10'),
-- (6, 255, '2015-03-12');
CREATE TABLE IF NOT EXISTS `biopsy_p1` (
`id` int(11) unsigned NOT NULL primary key,
`biopsy_p0_id` int(11) unsigned NOT NULL,
`introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
alter table biopsy_p1 add constraint fk_biopsy_p0
foreign key (biopsy_p0_id)
references biopsy_p0 (id)
on update cascade
on delete cascade;
INSERT INTO `biopsy_p1` (`id`, `biopsy_p0_id`, `introduced`)
VALUES
(1, 1, '2015-03-18'),
(2, 2, '2015-03-31'),
(3, 1, '2015-03-17'),
(4, 1, '2015-03-18'),
(5, 3, '2015-03-11'),
(6, 2, '2015-03-01');
我建议您根据它们的名称来命名,即不要命名id列id并在模型中的其他地方更改它们的名称。例如:
CREATE TABLE IF NOT EXISTS biopsy (
biopsy_id int unsigned NOT NULL primary key,
creation_date date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;
但我将把它放在一边。现在我们知道数据是一致的:
select x.id as biopsy_id, x.creation_date
, y.id as biopsy_p0_id, y.introduced as biopsy_p0_introduction
, z.id as biopsy_p1_id, z.introduced as biopsy_p1_introduction
from biopsy as x
left join biopsy_p0 as y
on y.biopsy_id = x.id
left join biopsy_p1 as z
on z.biopsy_p0_id = y.id
order by x.id, y.id, z.id;
+-----------+---------------+--------------+------------------------+--------------+------------------------+
| biopsy_id | creation_date | biopsy_p0_id | biopsy_p0_introduction | biopsy_p1_id | biopsy_p1_introduction |
+-----------+---------------+--------------+------------------------+--------------+------------------------+
| 226 | 2015-03-08 | 1 | 2014-12-31 | 1 | 2015-03-18 |
| 226 | 2015-03-08 | 1 | 2014-12-31 | 3 | 2015-03-17 |
| 226 | 2015-03-08 | 1 | 2014-12-31 | 4 | 2015-03-18 |
| 226 | 2015-03-08 | 2 | 2014-12-31 | 2 | 2015-03-31 |
| 226 | 2015-03-08 | 2 | 2014-12-31 | 6 | 2015-03-01 |
| 226 | 2015-03-08 | 3 | 2014-12-31 | 5 | 2015-03-11 |
| 227 | 2015-03-08 | 4 | 2015-03-14 | NULL | NULL |
+-----------+---------------+--------------+------------------------+--------------+------------------------+
7 rows in set (0.00 sec)
剩下的仅仅是表示,最好用php来完成
对于您的一般问题,是否最好将结构信息保存在一个表中,我想说,如果您有少量的固定级别,您的解决方案就可以了
对于大量级别,或者如果数字未知,则需要某种递归结构注意,您还需要提出此类问题的方法,现在大多数DBMS:s都有递归公共表表达式,但MySQL没有。你可以用变量来解决某些问题,但很快就会变得一团糟。Troels Arvin的链接集位于:
您可能会觉得有用。将右连接更改为左连接谢谢您的回复。我已经试过了,但它也只给了我尾注。所以只有-Second-levela-Second-levelb等等。您能提供示例数据来说明问题创建表和插入语句吗?我现在为这个问题添加了一个PHP解决方案。但是这真的不好,所以如果有任何想法我可以用SQL来管理它,我将不胜感激!这个结果将数据合并并格式化,与我预期的不同。这肯定比我的解决方案更好。也谢谢你的链接,非常感谢。很高兴它有帮助,在SO和其他地方搜索关于主题的有用术语是嵌套集、物化路径和传递闭包。
CREATE TABLE IF NOT EXISTS `biopsy` (
`id` int(11) unsigned NOT NULL primary key,
`creation_date` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;
INSERT INTO `biopsy` (`id`, `creation_date`) VALUES
(226, '2015-03-08'),
(227, '2015-03-08');
CREATE TABLE IF NOT EXISTS `biopsy_p0` (
`id` int(11) unsigned NOT NULL primary key,
`biopsy_id` int(11) unsigned NOT NULL,
`introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
alter table biopsy_p0 add constraint fk_biopsy
foreign key (biopsy_id)
references biopsy (id)
on update cascade
on delete cascade;
INSERT INTO `biopsy_p0` (`id`, `biopsy_id`, `introduced`) VALUES
(1, 226, '2014-12-31'),
(2, 226, '2014-12-31'),
(3, 226, '2014-12-31'),
(4, 227, '2015-03-14');
-- violates the f.k. introduced
-- (5, 255, '2015-03-10'),
-- (6, 255, '2015-03-12');
CREATE TABLE IF NOT EXISTS `biopsy_p1` (
`id` int(11) unsigned NOT NULL primary key,
`biopsy_p0_id` int(11) unsigned NOT NULL,
`introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
alter table biopsy_p1 add constraint fk_biopsy_p0
foreign key (biopsy_p0_id)
references biopsy_p0 (id)
on update cascade
on delete cascade;
INSERT INTO `biopsy_p1` (`id`, `biopsy_p0_id`, `introduced`)
VALUES
(1, 1, '2015-03-18'),
(2, 2, '2015-03-31'),
(3, 1, '2015-03-17'),
(4, 1, '2015-03-18'),
(5, 3, '2015-03-11'),
(6, 2, '2015-03-01');
CREATE TABLE IF NOT EXISTS biopsy (
biopsy_id int unsigned NOT NULL primary key,
creation_date date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;
select x.id as biopsy_id, x.creation_date
, y.id as biopsy_p0_id, y.introduced as biopsy_p0_introduction
, z.id as biopsy_p1_id, z.introduced as biopsy_p1_introduction
from biopsy as x
left join biopsy_p0 as y
on y.biopsy_id = x.id
left join biopsy_p1 as z
on z.biopsy_p0_id = y.id
order by x.id, y.id, z.id;
+-----------+---------------+--------------+------------------------+--------------+------------------------+
| biopsy_id | creation_date | biopsy_p0_id | biopsy_p0_introduction | biopsy_p1_id | biopsy_p1_introduction |
+-----------+---------------+--------------+------------------------+--------------+------------------------+
| 226 | 2015-03-08 | 1 | 2014-12-31 | 1 | 2015-03-18 |
| 226 | 2015-03-08 | 1 | 2014-12-31 | 3 | 2015-03-17 |
| 226 | 2015-03-08 | 1 | 2014-12-31 | 4 | 2015-03-18 |
| 226 | 2015-03-08 | 2 | 2014-12-31 | 2 | 2015-03-31 |
| 226 | 2015-03-08 | 2 | 2014-12-31 | 6 | 2015-03-01 |
| 226 | 2015-03-08 | 3 | 2014-12-31 | 5 | 2015-03-11 |
| 227 | 2015-03-08 | 4 | 2015-03-14 | NULL | NULL |
+-----------+---------------+--------------+------------------------+--------------+------------------------+
7 rows in set (0.00 sec)