Postgresql选择字符串是否包含
因此,我的Postgresql中有一个:Postgresql选择字符串是否包含,sql,postgresql,Sql,Postgresql,因此,我的Postgresql中有一个: TAG_TABLE ========================== id tag_name -------------------------- 1 aaa 2 bbb 3 ccc 为了简化我的问题, 当字符串“aaaaaa”包含“TAG\u name”时,我要做的是从TAG\u表中选择“id”。 因此,理想情况下,它应该只返回“1”,这是
TAG_TABLE
==========================
id tag_name
--------------------------
1 aaa
2 bbb
3 ccc
为了简化我的问题,
当字符串“aaaaaa”包含“TAG\u name”时,我要做的是从TAG\u表中选择“id”。
因此,理想情况下,它应该只返回“1”,这是标记名“aaa”的ID
这就是我目前正在做的:
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaaaaa' LIKE '%tag_name%'
但显然,这不起作用,因为postgres认为“%tag_name%”表示包含子字符串“tag_name”的模式,而不是该列下的实际数据值
如何将标记名传递给模式???您应该在引号外使用“标记名”;然后将其解释为记录的一个字段。使用“| |”与文字百分比符号连接:
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || tag_name || '%';
我个人更喜欢~operator的简单语法
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' ~ tag_name;
值得通读以了解差异。
`搜索子字符串的正确方法是使用
位置
函数,而不是像表达式那样的,它需要转义%
,\uuu
和转义字符(\
默认值):
除了像“%”| | | tag | u name | |‘%”这样带有aaaaaaaa的解决方案之外,还有
是位置
(与args的顺序相反)和strpos
SELECT id FROM TAG_TABLE WHERE strpos('aaaaaaaa', tag_name) > 0
除了效率更高(LIKE看起来效率更低,但索引可能会改变情况)之外,LIKE还有一个非常小的问题:tag_name当然不应该包含%
,尤其是
(单字符通配符),以避免误报
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || "tag_name" || '%';
tag\u name
应该在引号中,否则它会给出错误,因为tag\u name不存在当tag\u name是“drop table tag\u table;”--“
?@Denis:什么都没有发生。没有行,因为WHERE
子句的计算结果为FALSE
。该语句不是动态的,只连接了值,没有SQL注入的机会。aaaa和tag_name的顺序不应该颠倒吗?我的意思是你应该在后面加一个列名where@user151496否,因为模式必须位于LIKE
关键字的右侧。请注意,在LIKE
模式中使用变量可能会产生意外后果,因为这些变量包含下划线(u)或百分比字符(%)。可能需要转义这些字符,例如使用此函数:CREATE或REPLACE function quote\u for_like(text)返回文本语言SQL不可变为$$SELECT regexp\u REPLACE($1'([\%\u]),'\\\1',g');$
(来自Freenode上的#postgresql IRC频道的用户MatheusOl)。只有当tag_name
是正确的正则表达式时,这才有效。相当危险。@JakubFedyczak要匹配文字标记_name,您可以使用中提到的***=
。然而,我发现,与strpos
/位置
解决方案相比,这要慢得多。这与公认的解决方案正好相反。您正在以字符串的形式连接,而它需要是一个列…双引号仍然引用一个列,所以这将是相同的⸻在列名中有空格的情况下,我必须将strpos替换为position,因为strpos总是为meThis返回0是正确的方法。任何人都不应该使用hacky regex方法。LIKE
和ILIKE
可以使用gin
索引<代码>位置
不能。@Grigory您的位置
一定是打字错误。
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || "tag_name" || '%';