我在SQL的一个列中有一个字段,用于连接给定用户已查看过的产品。它以“SKU1,SKU2,SKU3,......”的形式存储。示例字符串为“1,2,4,6,13,15,16”。
我想查看此列中包含“6”的所有行。我会使用LIKE,但它也会得到16,26,36等。
SELECT rows
FROM table
WHERE column LIKE '%6%'
-- will get 6, 16, 26, ...
SELECT rows
FROM table
WHERE column LIKE '%6%'
AND column NOT LIKE '%16%'
AND column NOT LIKE '%26%'
...
...
-- will get 6, but only in rows without 16, 26, ...
我希望所有包含“6”的行,但不包含“16”,“26”等的行,而不是“6”。我确实想要单独包含“6”,“6”和“16”,“26”等的行,而不是包含“6”或“16”,“26”等的行。我缺少什么?
答案 0 :(得分:3)
您在设计数据库时犯了一个根本性的错误。正确的解决方案是使用单独的表替换列column
。此表将包含两列,即用户ID和产品ID,并且对于用户已审阅的每个产品,将有一个单独的行。然后,您可以轻松获得所需的信息。
如果不这样做,你将不得不编写一个包含三个部分的复杂WHERE子句来测试“%,6,%”(前后空格或“6,%”或“%,6”。这将是执行速度慢,因为数据库变大,不可索引,不可JOIN,并且不受参考完整性的影响。如果在存储数据时使用空格不一致,搜索表达式会变得更复杂。
请注意,某些SQL数据库(您没有说明您使用的是哪种)具有子字符串函数,以使这种搜索稍微容易一些,但即使在这些数据库中,设计仍然是对关系原则和第一范式的严重违反并应尽早重构。
答案 1 :(得分:1)
这个条件会给你你正在寻找的结果。
mycolumn like "%,6,%" or mycolumn like '6,%' or mycolumn like '%,6'
这里'我使用的是逗号会出现在6的两边,除非6位于字符串的开头或结尾。
答案 2 :(得分:1)
你有一个糟糕的数据库设计,但你可以做你想要的:
WHERE ','||column||',' LIKE '%,6,%'
您真正想要的是一个联结表,其中一列用于SKU,另一列用于标识该行所属的内容。
你知道,SQL有一个很好的机制来存储事物列表。它被称为表,而不是逗号分隔列表。将ID存储在列中的一些重要问题:
答案 3 :(得分:-1)
如果您的数据库允许,您应该检查是否有某些内容,例如,
CHARINDEX (',6,', CONCAT(',', yourColumn, ',')) > 0
对于SQL Server或
WHERE INSTR(',' || yourColumn || ',', ',6,') > 0
for Oracle的性能优于基于LIKE
的解决方案。 (一旦你在它,请验证索引对相关列的影响,以替代查询。)
但是,当然,只有改变你的数据库设计 - 如上所述 - 这是不可取的。