我遇到了这个问题:
实体有一个名字。实体可以属于多个父母。实体可以有多个孩子。儿童可以有多个孩子等。实体名称是唯一的。
提供一个解决方案,可以检索来自任何特定实体的所有父母,兄弟姐妹和孩子 - 但不是祖父母或孙子女,因此当前深度为+/- 1级。结果集中不返回给定的实体。
按名称对结果集进行排序,并且应清除关系状态(parent,sibling,child)。结果集应该支持分页。
可用的工具是PHP 7和MySQL 5.7
是的,这是大学的任务,你不是来做我的作业,但我非常困难,并且会喜欢指向正确的方向。
我决定制作2张表,样本数据如下:
CREATE TABLE `entities` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
CREATE TABLE `entity_relations` (
`id_entity` int(11) unsigned NOT NULL,
`id_parent` int(11) NOT NULL,
UNIQUE KEY `id_parent` (`id_parent`,`id_entity`)
) ;
INSERT INTO `entities` (`id`, `name`)
VALUES
(1,'Parent 1'),
(2,'Parent 2'),
(3,'Parent 3'),
(4,'Parent 4'),
(5,'Sibling 1'),
(6,'Sibling 2'),
(7,'Sibling 3'),
(8,'Sibling 4'),
(9,'Sibling 5'),
(10,'Child 1'),
(11,'Child 2'),
(12,'Grandchild 1');
INSERT INTO `entity_relations` (`id_entity`, `id_parent`)
VALUES
(1,0),
(2,0),
(3,0),
(4,0),
(5,1),
(8,1),
(5,2),
(7,2),
(6,3),
(7,3),
(9,3),
(6,4),
(10,5),
(11,5),
(12,10);
现在问题是获取所需结果集所需的查询。如果我搜索“兄弟1”作为我的实体名称,我应该得到以下数据:
Name | Relation
-----------------
child 1 | child
child 2 | child
parent 1 | parent
parent 2 | parent
sibling 3 | sibling
sibling 4 | sibling
由于要求声明它应该支持分页,我认为所有这些都应该在SQL中发生。我当然可以从PHP做出3个不同的查询,一个用于父项,一个用于兄弟,一个用于子项,在数组中合并并按名称排序,然后从该数组中取出一个子集,但这似乎不是是最有效的方式。所以我决定试一试SQL。
到目前为止,我提出了这个问题:
select e.*
from entities e
join entity_relations er on er.id_entity = e.id
join entity_relations err on err.id_parent = e.id
where er.id_parent in ( -- children
select e.id
from entities e
where e.name = "Sibling 1"
)
or err.id_entity in ( -- parents
select e.id
from entities e
where e.name = "Sibling 1"
)
order by e.name asc;
但那已经不起作用了,它只给了我父母而不是孩子。兄弟姐妹甚至还不在查询中。
有人能指出我正确的方向吗?我的桌子结构对此有用还是应该做一些完全不同的事情?
因为没有限制我可以使用它的MySQL工具意味着存储过程也在桌面上,这些会有用吗?
我真的想学习这一点,所以理解为什么要做出某些选择是我最想要的。
答案 0 :(得分:1)
我会给你一个没有名字的方法:;
select e.*
from entities e
where e.id in (select er.id_parent
from entity_relationships er
where er.id_entity = ?
) or
e.id in (select er.id_entity
from entity_relationships er
where er.id_parent = ?
);
?
是实体 id 的占位符。
我会让你修改查询来处理名字。
Here是一个SQL小提琴。
答案 1 :(得分:-1)
好的,我现在得到了它,它给了我正确的结果。但我不禁想知道这是否是“正确”的做法。所有反馈都非常赞赏
编辑:现在删除了许多子选择并使用连接:
SELECT e.name AS name, 'parent' AS relation
FROM entities e
RIGHT JOIN entity_relations er ON er.id_parent = e.id
RIGHT JOIN entities origin ON origin.id = er.id_entity
WHERE origin.name = "Sibling 1"
UNION ALL
SELECT e.name AS name, 'child' AS relation
FROM entities e
RIGHT JOIN entity_relations er ON er.id_entity = e.id
RIGHT JOIN entities origin ON origin.id = er.id_parent
WHERE origin.name = "Sibling 1"
UNION ALL
SELECT e.name AS name, 'child' AS relation
FROM entities e
RIGHT JOIN entity_relations er on er.id_entity = e.id
WHERE er.id_parent IN (
SELECT id_parent
FROM entity_relations er
LEFT JOIN entities e ON er.id_entity = e.id
WHERE e.name = "Sibling 1"
)
AND e.name != "Sibling 1";
ORDER BY name ASC;
有关这是否是一种有效的方法的任何想法?如果没有,有什么可以改进的?
为了好奇;如果表格中存在沉浸式的行数和关系,这还能表现得好吗?数百万?
我当然明白,在这种情况下,可能会有比(My)SQL更好的选项,但如果没有?