一个简单的问题是php中的preg_match
和mysql查询中的like
是相同的吗?
主要问题:
下面是我的两张表,表1和表2
Table 1 Table 2
+-------+-------------------------+ +-------+------------------------------+ | ID | Model | | ID | Model | +-------+-------------------------+ +-------+------------------------------+ | 1 | iPad 2 WiFi 16GB | | 1 | iPad2 WiFi 16GB | | 2 | iPhone 4S 16GB | | 2 | iPhone4S 16GB | | 3 | iPod Touch(4th Gen)8GB | | 3 |iPod Touch 4th Generation 8GB | +-------+-------------------------+ +-------+------------------------------+
Now what i wanna do is to compare these two tables as you can see iPad 2 WiFi 16GB
and iPad2 WiFi 16GB
or iPod Touch(4th Gen)8GB
and iPod Touch 4th Generation 8GB
both are the same but it doesnot show if i put in my query where Table1.model = Table2.model
because they are not the exact match. What I wanna do is to compare these rows with mysql query by using like
or anyother way so it'll compare the both table rows which are alike. Kindly let me know how to write such sql query.
I tried the following sql query but it didnot return all the rows like it didnot return those type of rows that are mentioned in the above example.
SELECT table1.model as model1, table2.model as model2
FROM table1,table2 WHERE table1.model REGEXP table2.model
最佳答案
两个问题-描述是标准的(描述不变)还是用户输入的?如果它们是标准列,则添加一个整数列并对此列进行比较。
如果它是由用户输入的,则您的工作会更复杂,因为您正在寻找更模糊的搜索。我使用了一个双程序搜索算法来对两个字符串之间的相似性进行排序,但这不能在mysql中直接完成。
可以使用like代替模糊搜索,但如果最终将“%”放在搜索词的开头,则其效率仅限于执行表扫描。此外,它还意味着您可以在选择的子字符串部分获得匹配,这意味着您需要提前知道子字符串。
一旦我知道你想做什么,我很乐意再详细说明。
编辑1:好的,考虑到你的精雕细琢,你需要像我提到的那样做一个模糊风格的搜索。我使用了一个bi gram方法,它包括获取用户所做的每个条目,并将其分成2或3个字符的块。然后,我将这些块存储在另一个表中,并将每个条目键回到实际描述。
例子:
描述1:“快速前进”
说明2:“短跑前进”
如果将每个字符分为两个字符块-“a”、“f”、“fa”、“as”、“st”……
然后,您可以比较两个字符串匹配的两个字符块的数量,得到一个“分数”,这意味着两者之间的准确性或相似性。
如果我不知道您使用的是什么开发语言,我将不考虑实现,但这需要在mysql中不显式地完成。
或者懒惰的替代方法是使用类似亚马逊的云搜索服务,该服务将根据你给出的术语提供搜索……但不确定它们是否允许你不断添加新的描述以供考虑,而且根据你的应用程序,可能会有点昂贵(imho)。
R
有关bigram实现的另一篇so文章-请参见SO bigram / fuzzy search
——根据提问者的阐述进行更新---
首先,我假设您阅读了我提供的链接的理论。其次,我将尽量保持它与数据库无关,因为它不需要mysql(尽管我使用它,而且它工作得非常好)
好的,所以bigram方法只有在可能的匹配比较小的情况下才能在内存数组中正常工作,否则它会很快受到表扫描性能的影响,比如没有索引的mysql表。因此,您将使用数据库的优势来帮助您进行索引。
您需要一个表来保存用户输入的“术语”或您要比较的文本。最简单的形式是一个包含两列的表,一个是唯一的自动递增整数,它将被索引,我们将在下面调用hd_id,第二个是varchar(255),如果字符串很短,或者文本很长,可以任意命名。
然后,您需要创建另一个至少有三列的表-一列作为引用列返回到另一个表的自动递增列(我们将在下面调用此hd_id),第二列将是最多5个字符的varchar()(这将保存您的bigram块),我们将称之为“bigram”在下面,第三列是一个自动递增的列,名为b_id below。此表将保存每个用户条目的所有大图,并与整个条目相关联。您需要单独为varchar列编制索引(或者在复合索引中按顺序排列)。
现在,每当用户输入您要搜索的术语时,您需要在第一个表中输入该术语,然后将该术语分解为大图,并使用对第一个表中的整个术语的引用将每个块输入到第二个表中,以完成关系。这样,在php中进行剖析,但是让mysql或任何数据库为您进行索引优化。在bigram阶段存储表1中为计算阶段生成的bigram的数量可能会有帮助。下面是一些php代码,让您了解如何创建bigram:
// split the string into len-character segments and store seperately in array slots
function get_bigrams($theString,$len)
{
$s=strtolower($theString);
$v=array();
$slength=strlen($s)-($len-1); // we stop short of $len-1 so we don't make short chunks as we run out of characters
for($m=0;$m<$slength;$m++)
{
$v[]=substr($s,$m,$len);
}
return $v;
}
不要担心字符串中的空格-如果考虑模糊搜索,它们实际上非常有用。
所以你得到了大图,把它们输入到一个表中,通过和索引列链接到表1中的整个文本…现在怎么办?
现在,每当您搜索诸如“我最喜欢的搜索项”之类的术语时,您可以使用php函数将其转换为一个bigram数组。然后使用此命令在bigram表(2)上创建sql语句的in(..)部分。下面是一个例子:
select count(b_id) as matches,a.hd_id,description, from table2 a
inner join table1 b on (a.hd_id=b.hd_id)
where bigram in (" . $sqlstr . ")
group by hd_id order by matches desc limit X
我将$sqlstr留作php字符串引用-您可以使用内爆或从get-bigrams或parametize返回的数组中的任何内容(如果您喜欢的话)将它自己构造为一个逗号分隔的bigram函数列表。
如果正确完成,上面的查询将根据所选bigram的长度返回最匹配的模糊搜索项。根据您对整个搜索字符串的预期长度,您选择的长度具有相对有效性。
最后,上面的查询给出了一个模糊的匹配等级。您不仅可以比较匹配项,还可以比较匹配项与总体bigram计数,从而帮助消除长搜索字符串与短字符串之间的偏差,从而进行改进。我在这里停下来是因为在这一点上,它变得更加特定于应用程序。
希望这有帮助!
R
关于php - 模式与两个表列之间的mysql进行比较,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13417194/