1

我的数据库构建如下:

  1. 值1,值2,值3 | 1
  2. 值 4,值 5,值“u6 | 2
  3. 值 5,值 6,值 8 |3

(两列,一列有一个用逗号分隔的键,另一列只是一个普通的 var-char)

我正在寻找在引号中查找查询的最可靠方法,但我在这里有点迷路了。

我为此使用了边界一词:

SELECT * FROM ABC WHERE content REGEXP '[[:<:]]value 5[[:>:]]'

问题是当我做这个查询时:

SELECT * FROM ABC WHERE content REGEXP '[[:<:]]5[[:>:]]'

它还将返回值,这不是我想要的。另一个问题是单词边界将引号称为单词边界

我该如何解决这个问题并创建一个仅获取引号之间的确切完整查询的简单查询?

顺便说一句,我没有更改数据库结构的选项...

4

2 回答 2

4

正如@MarcB 评论的那样,您确实应该尝试规范化您的架构:

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 连接并对结果进行分组:

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)
于 2012-12-03T15:04:56.893 回答
0

另一种解决方法是将 LIKE 与列表中项目的分隔符一起使用:

WHERE content LIKE ',5,'

但是您要查找的项目可能位于列表的开头或结尾。因此,您必须即时修改列表以在开头和结尾包含分隔符。

WHERE CONCAT(',', content, ',') LIKE '%,5,%'  -> this works for me on mysql

这很有效,从某种意义上说,它并不比您为逗号分隔列表中的项目所做的任何其他搜索差。那是因为这样的搜索必然会进行表扫描,因此效率非常低。随着表中数据的增长,您会发现它的性能不足以发挥作用。

另请参阅我对在数据库列中存储分隔列表真的那么糟糕吗?

于 2012-12-03T15:17:16.590 回答