我的数据库构建如下:
(两列,其中一列用逗号分隔,另一列只是普通的var-char)
我正在寻找在报价中找到查询的最可靠方式,我在这里有点迷失。
我正在使用单词边界:
SELECT * FROM ABC WHERE content REGEXP '[[:<:]]value 5[[:>:]]'
问题出在我正在进行此查询时:
SELECT * FROM ABC WHERE content REGEXP '[[:<:]]5[[:>:]]'
它也将返回值,这不是我正在寻找的。另一个问题是单词边界将引号称为单词边界
如何解决此问题并创建一个简单的查询,只能在引号之间获取完全完整的查询?
顺便说一句 我没有选择更改数据库结构...
答案 0 :(得分:4)
作为@MarcB commented,您真的应该尝试normalise您的架构:
CREATE TABLE ABC_values (
id INT,
content VARCHAR(10),
FOREIGN KEY (id) REFERENCES ABC (id)
);
INSERT INTO ABC_values
(id, content)
VALUES
(1, 'value1'), (1, 'value2'), (1, 'value3'),
(2, 'value4'), (2, 'value5'), (2, 'val"u6'),
(3, 'value 5'), (3, 'value 6'), (3, 'value 8')
;
ALTER TABLE ABC DROP content;
然后,根据需要,您可以在表格之间执行SQL join并对结果进行分组:
SELECT id, GROUP_CONCAT(ABC_values.content) AS content
FROM ABC LEFT JOIN ABC_values USING (id) NATURAL JOIN (
SELECT id FROM ABC_values WHERE content = 'value 5'
) t
GROUP BY id
如果完全无法更改架构,您可以尝试FIND_IN_SET()
:
SELECT * FROM ABC WHERE FIND_IN_SET('value 5', content)
答案 1 :(得分:0)
另一种解决方法是将LIKE用于列表中项目的分隔符:
WHERE content LIKE ',5,'
但您要查找的项目可能位于列表的开头或结尾。因此,您必须动态修改列表,以在开头和结尾包含分隔符。
WHERE CONCAT(',', content, ',') LIKE '%,5,%' -> this works for me on mysql
这是有效的,在某种意义上,它并不比您对逗号分隔列表中的项目执行的任何其他搜索更糟糕。那是因为这样的搜索必然会进行表扫描,因此效率非常低。随着表格中数据的增长,您会发现它无法很好地发挥作用。
另请参阅我对Is storing a delimited list in a database column really that bad?
的回答