2011-09-14 108 views
1
$SQL = "SELECT * FROM `user_posts` WHERE (`post` LIKE '%@".$user."%')"; 

例如,如果我的用户名是@Jake,它将显示任何包含@Jake的帖子。但它也会做例如@ Jake11,它也会显示。我怎样才能解决这个问题?MySQL喜欢查询但不喜欢其他

+0

所以你想让它只显示@Jake? –

+0

现在有几个如何在这里执行此操作的示例,但是如果您希望在页面加载时运行此操作,它们将会表现得非常糟糕。没有索引的任何东西都表现不佳。最好在帖子后从帖子中提取“@Name”,并在索引表中创建一个引用('post_mention.post_id' ='post.id' &&'post_mention.name' =“@Jake”)或者让批处理过程找到“@Name”提及并创建一个索引。 – six8

回答

3

你可能会考虑使用某种regular expression而不是LIKE '%...%'

一个例子可能是:

... WHERE `post` REGEXP '@" . mysql_real_escape_string($user) . "[[:>:]]'" 

一个正确的字边界上的[[:>:]]比赛。正如Bill Karwin指出的那样,在这种情况下不需要左侧边界模式,因为在@字符处存在隐含的字边界。 (事实上​​,你不能有一个左边界到非字字符的左侧。)

(我相信其他人会得上你可能接触到SQL injection攻击发表评论。)

+1

+1我写了一个类似的答案,但是你先发布。 :)顺便说一句,你可能不需要左手边界模式; '@'本身可能足以将匹配限制为只有你想要的字符串。没有要求使字边界模式平衡。 –

+0

这样做似乎没有返回任何数据。 – Jake

+0

谢谢比尔。我把左边的边界作为例子,但是我认为这可能会打破表达。所以我纠正了。 –

0

它看起来像你没有必要像在这里,一个简单的平等检查将工作:

$SQL = "SELECT * FROM `user_posts` WHERE (`post` = '@".$user."')"; 

被警告,你在这里有一个SQL注入的可能性,应使用mysql_real_escape_string

$SQL = sprintf("SELECT * FROM `user_posts` WHERE (`post` = %s)", mysql_real_escape_string('@' . $user)); 

如果你想后,您可以添加在你喜欢的项目空间内找到@Joe,但这会慢慢进行:

$SQL = sprintf("SELECT * FROM `user_posts` WHERE (`post` LIKE %s)", mysql_real_escape_string('% @' . $user . ' %')); 

出于性能使用FULLTEXT指数:

$SQL = sprintf("SELECT * FROM `user_posts` WHERE MATCH (post) AGAINST (%s)", mysql_real_escape_string('@' . $user)); 
+0

这只会匹配后只包含“@”的地方。 $ user' – Joe

+0

啊,现在我明白了,帖子必须是文本列。编辑。 – six8

0
$SQL = "SELECT * FROM `user_posts` WHERE (`post` LIKE '%@".$user."')"; 
+1

这只会匹配后缀“@”的地方。 $ user' – Joe

0

http://devzone.zend.com/article/1304

使用FULLTEXT列:)

ALTER TABLE user_posts ADD FULLTEXT(post); 

$sql = ' SELECT * FROM user_posts WHERE MATCH (post) AGAINST ("' . $user . '") '; 
+0

FWIW,FULLTEXT索引仅在当前版本的MySQL的MyISAM表中受支持,但InnoDB全文实现据称将在未来发布,可能在MySQL 5.6中。 –

+0

我发现它一般是MyISAM的定义特征。如果我想全文搜索,我会使用MyISAM,如果我想使用外键,我会使用InnoDB。我很少想要两个:P – Joe

+0

胜过全文索引和外键的问题是,如果你很难呼吸MyISAM,MyISAM会被损坏。 InnoDB也可能会被破坏,但在自动恢复方面会更好。 –

0

的 '%' 是一个通配符,它​​会匹配任何该点的字符数量。从你的查询中删除这些,你就会被设置。什么查询是在说,“发现有岗匹配的行[什么] @Jake [任何]”

它听起来并不像你想使用类似,只是做:

$SQL = "SELECT * FROM `user_posts` WHERE (`post` = '@".$user."')"; 
+0

这只会匹配后只包含“@”的地方。 $ user' – Joe

+0

是的,那是OP想要的,对吧? – Landon

+0

“任何有@Jake的帖子” – Joe

0

这种查询不会使用索引,并且需要全表扫描。一旦数据库增长到合理的大小,这显然会非常缓慢。理想情况下,创建帖子时,可以解析文本并在一对多表格中正确插入行(正确编制索引)以标识关系。

0

使用正则表达式:

$SQL = "SELECT * 
     FROM `user_posts1 
     WHERE (`post` LIKE '%@".$user."%) 
     AND (`post` NOT RLIKE '%@".$user."[a-zA-Z0-9]%')" 

在您的例子的情况下,这将包括@jake只要字符紧随其后的“杰克”($user)不是A和Z,A和Z之间或0-A。