在MySQL表中,我有一个名为ShareID的VARCHAR列。
我想获取ShareID为 1 的所有行。即仅此处的第一行和第二行。
我尝试使用LIKE命令,如下所示:
SELECT * FROM tablename WHERE ShareWithID LIKE '1%';
但这将捕获其中包含数字 1 的所有行,即不是我想要的行#3。
我想运行一条仅返回上面的行#1和#2的命令,因为其中包含的共享ID为 1 。
我尝试了各种命令(包括REGEXP和IN),并管理了一种“快速”解决方案,在该解决方案中,我在ShareID列中的每个数字后都添加了逗号,包括最后一个(即 10,1, ),然后执行以下命令:
SELECT * FROM tablename WHERE ShareWithID LIKE '%1,%';
但我宁愿使用适当的解决方案,而不要使用固定的解决方案。
任何指导都将受到欢迎。
答案 0 :(得分:2)
您不应将数字列表存储在以逗号分隔的字符串中。这是一个非常糟糕的主意:
尽管如此,有时候,我们在设计数据库的过程中确实被其他人束之高阁。 MySQL在这种情况下具有便捷的功能:
where find_in_set(1, ShareWithID) > 0
如果字符串中有空格,则需要删除它们:
where find_in_set(1, replace(ShareWithID, ' ', '')) > 0
答案 1 :(得分:1)
...将使用内置功能
FIND_IN_SET()
实际上不用于包含逗号分隔列表的字符串。它旨在与MySQL的SET data type一起使用。因此,名称为FIND_IN_SET()
,而不是FIND_IN_COMMA_SEPARATED_LIST()
。
对于MySQL,当原始“表”中的一列也可以完成这项工作时,节省了浪费时间来构建25万行的“表”(是它??)来照顾几列ID。 >
25万行不是问题。我管理给定表中具有 billions 行的数据库。如果您对索引进行基本的查询优化,那么对25万行的表中的大多数查询就可以了。
而使用逗号分隔的列表,则可能会破坏优化查询的任何机会。索引无助于搜索可能不是字符串最左前缀的子字符串,而在以逗号分隔的列表中搜索数字基本上是在搜索子字符串。
您正在使用逗号分隔的列表来使查询无法优化。每个使用FIND_IN_SET()
的查询都将是一个表扫描,与表中的行数呈线性关系会变慢。
除索引外,使用逗号分隔的列表还有其他缺点,这是我在对这则旧帖子的回答中写到的:Is storing a delimited list in a database column really that bad?
我宁愿使用适当的解决方案,也不要使用笼罩的解决方案。
然后每行存储一个ID。在关系数据库中,这是正确的解决方案。
答案 2 :(得分:0)
此问题的解决方案是将Gordon Linoff对FIND_IN_SET命令的建议与有关表列的正确配置结合使用,如下所示:
SELECT * FROM tablename WHERE FIND_IN_SET('1', ShareWithID);
然而,因为FIND_IN_SET命令可以找到的字符串中的位置一个的 逗号分隔 强>的字符串列表,必须确保的是,列的内容包含逗号每个项目后,不包含逗号后的空格。
因此,与上述命令结合使用的此列内容将返回“ 0”行: 111,1
此列内容将返回“ 1”行: 111,1
这将是: 33,1
这是: 44,1,415