我的php mysql查询有一个小问题,我正在寻求帮助。
我有一个家谱表,我在那里存储他/她的祖先用逗号分隔的每个人。像这样
id ancestors
10 1,3,4,5
所以身份10的人是由id 5生成的,他是由4岁等人生的... ...
现在我希望选择所有在其祖先中拥有id x的人,因此查询将类似于: 从祖先喜欢'%x%'
的人中选择*现在这可以正常工作,除非,如果id x是2,并且记录有祖先id 32,这个查询将检索32因为32包含2.如果我使用'%,x, %' (包括逗号)查询将忽略其祖先x位于列的边缘(左侧或右侧)的记录。它也会忽略其中x是唯一祖先的记录,因为不存在逗号。
简而言之,我需要一个类似的查询来查找一个表达式,该表达式被逗号包围或者没有被任何东西包围。或者获取正则表达式的查询,前提是没有数字。我需要它尽可能高效(我很喜欢写正则表达式)
谢谢。
编辑:好的,帮助我想出一个更好的架构。
答案 0 :(得分:2)
您没有以正确的方式存储数据。无论如何,如果您仍想使用此架构,则应使用FIND_IN_SET而不是LIKE来避免不良后果。
SELECT *
FROM mytable
WHERE FIND_IN_SET(2, ancestors) <> 0
答案 1 :(得分:1)
您应该考虑重新设计数据库结构。添加新表&#34;祖先&#34;到列数据库:
id id_person ancestor
1 10 1
2 10 3
3 10 4
之后使用JOIN查询&#34; WHERE IN&#34;选择正确的行。
答案 2 :(得分:1)
由于数据库设计错误,您遇到了这个问题。基于DBMS的第一个数据库并不适用于这类数据,基于图形的数据库更容易适应对于这种解决方案。
如果它包含少量数据你可以使用mysql,但如果你只关心他们的父亲那么设计仍然是错误的。然后只需向人(或任何你称之为)表添加一列。如果它的null - 没有父/未知 - 包含他父母的(int)。
如果您需要更多,那么只需要父亲&#39;关系你可以使用pivot table
来包含两个人的关系,但这不是一项简单的任务。
答案 3 :(得分:1)
在RDBMS中存在一些存储分层数据的既定方法。我发现此幻灯片在过去非常有用:
Models for Hierarchical Design
由于数据涉及祖先 - 因此你不会指望它经常改变 - 封闭表可以适应账单。
无论您选择哪种型号,请务必环顾四周,看看其他人是否已经实施过它。
答案 4 :(得分:0)
您可以将值存储为JSON数组
id | ancestors
10 | {"1","3","4","5"}
然后查询如下:
$query = 'select * from people where ancestors like \'%"x"%\'';
当然,更好的是使用多对多关系的映射表
答案 5 :(得分:0)
您可以使用regexp执行此操作:
SELECT * FROM mytable WHERE name REGEXP ',?(x),?'
其中x是您的搜索值
答案 6 :(得分:0)
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,ancestors VARCHAR(250) NOT NULL
);
INSERT INTO my_table VALUES(10,',1,3,4,5');
SELECT *
FROM my_table
WHERE CONCAT(ancestors,',') LIKE '%,5,%';
+----+-----------+
| id | ancestors |
+----+-----------+
| 10 | ,1,3,4,5 |
+----+-----------+
SELECT *
FROM my_table
WHERE CONCAT(ancestors,',') LIKE '%,4,%';
+----+-----------+
| id | ancestors |
+----+-----------+
| 10 | ,1,3,4,5 |
+----+-----------+