【问题标题】:mysql like query exclude numbersmysql like 查询排除数字
【发布时间】:2015-03-08 16:28:45
【问题描述】:

我有一个php mysql查询的小问题,我正在寻求帮助。

我有一个家谱表,我在其中为每个人存储他/她的祖先 id,用逗号分隔。像这样

 id ancestors
 10 1,3,4,5

所以id 10的人是id 5的父亲,id 5的父亲是id 4的父亲,id 4的父亲是3等等......

现在我希望选择所有祖先中具有 id x 的人,因此查询将类似于: 从祖先喜欢 '%x%' 的人中选择 *

现在这可以正常工作,除非,如果 id x 假设为 2,并且记录的祖先 id 为 32,这样的查询将检索 32,因为 32 包含 2。如果我使用 '%,x,%' (包括逗号)查询将忽略其祖先 x 位于列的任一边缘(左侧或右侧)的记录。由于不存在逗号,它还将忽略 x 是唯一祖先的记录。

简而言之,我需要一个like 查询来查找一个被逗号包围或不被任何东西包围的表达式。或者在没有数字的情况下获取正则表达式的查询。而且我需要它尽可能高效(我不擅长编写正则表达式)

谢谢。

编辑:好的,伙计们,帮我想出一个更好的架构。

【问题讨论】:

  • 你想出了一个糟糕的数据库设计。您将永远无法使其始终如一地工作或易于查询。您需要停下来阅读一下如何使用关系数据库创建一对多关系。只需做一个谷歌并沐浴在由此产生的知识中
  • 你应该阅读这个:stackoverflow.com/questions/3653462/…
  • 我知道一对多。通常我会为每条记录存储他的直接父记录。但是,如果我希望使用一个查询来获取给定记录的所有子孙,我该怎么做?我不想检索孩子,然后为他们的孩子单独查询,我想这样我会做一个查询并全部获取。
  • 实际上,物化路径在某些圈子里得到了很好的报道!

标签: php mysql regex


【解决方案1】:

您没有以正确的方式存储数据。无论如何,如果您仍想使用此模式,则应使用 FIND_IN_SET 而不是 LIKE 以避免不希望的结果。

SELECT *
  FROM mytable
 WHERE FIND_IN_SET(2, ancestors) <> 0

【讨论】:

  • 哇,五个答案并正确解决了这个问题。
【解决方案2】:

您应该考虑重新设计您的数据库结构。将新表“祖先”添加到包含列的数据库中:

id id_person ancestor
1  10        1
2  10        3
3  10        4

之后 -- 使用带有“WHERE IN”的 JOIN 查询来选择正确的行。

【讨论】:

  • 我愿意为 Stawberry 提供更好的建议,即使是在更改架构方面,所以开枪吧。
【解决方案3】:

您遇到此问题是因为数据库设计错误。第一个基于 DBMS 的数据库不适用于此类数据,基于图形的数据库更可能适合此类解决方案。

如果它包含少量数据,您可以使用 mysql 但设计仍然是错误的,如果您只关心他们的“父亲”,那么只需在 person(或您所称的)表中添加一列。如果它的 null - 没有父亲/否则未知 - 包含他的父母的 (int)。

如果您需要的不仅仅是“父亲”关系,您可以使用pivot table 来包含两个人的关系,但这不是一项简单的任务。

【讨论】:

  • 我认为说 DBMS 不适用于此类数据并不准确。其他解决方案可能会更有效/更有效地做到这一点,但设计合理的 DBMS 应该能够处理大量分层记录。
  • 如果它的效率较低,那么它不打算这样做。我不知道这个家谱的目的是什么,但如果你尝试建立多个/大家谱,你最终至少会等待几秒钟来获取树
【解决方案4】:

在 RDBMS 中存储分层数据的方法有几种。我发现这个幻灯片在过去很有帮助:

Models for Hierarchical Design

由于数据涉及祖先 - 因此您不会期望它经常更改 - 封闭表可能适合该法案。

无论您选择什么模型,一定要环顾四周,看看其他人是否已经实现了它。

【讨论】:

  • 显然我的是路径枚举
【解决方案5】:

您可以将值存储为 JSON 数组

id | ancestors
10 | {"1","3","4","5"}

然后查询如下:

$query = 'select * from people where ancestors like \'%"x"%\'';

当然更好的是为您的多对多关系使用映射表

【讨论】:

    【解决方案6】:

    你可以用正则表达式做到这一点:

    SELECT * FROM mytable WHERE name REGEXP ',?(x),?'
    

    其中 x 是您的搜索值

    【讨论】:

    • 为什么?我在一个示例 mysql (5.5) 数据库中对其进行了测试,这似乎工作正常
    • 我通过查找 id 3 对其进行了测试,它检索到包含 id 37 的行
    【解决方案7】:
    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  |
    +----+-----------+
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-26
      • 1970-01-01
      • 2019-01-04
      • 2017-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      相关资源
      最近更新 更多