Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 搜索:匹配多列中的所有单词_Php_Mysql_Regex_Search - Fatal编程技术网

Php 搜索:匹配多列中的所有单词

Php 搜索:匹配多列中的所有单词,php,mysql,regex,search,Php,Mysql,Regex,Search,我正在尝试向现有数据库中添加大量(1700个)名称,但需要检查重复的名称。事实上,我们假设大多数都是重复的。不幸的是,这些名称来自地址标签,并且没有用字段分隔(有些是组织名称,有些是人名)。为了减轻人类的负担,我想先搜索名字上的匹配项。所谓良好匹配,我的意思是我希望名称(John Julie Smith)中的所有单词在多个db字段(title、firstname、lastname、suffix、spoosename)中匹配。因此,如果姓约翰,姓史密斯,姓朱莉,这会匹配,或者如果姓约翰,姓朱莉,姓

我正在尝试向现有数据库中添加大量(1700个)名称,但需要检查重复的名称。事实上,我们假设大多数都是重复的。不幸的是,这些名称来自地址标签,并且没有用字段分隔(有些是组织名称,有些是人名)。为了减轻人类的负担,我想先搜索名字上的匹配项。所谓良好匹配,我的意思是我希望名称(John Julie Smith)中的所有单词在多个db字段(title、firstname、lastname、suffix、spoosename)中匹配。因此,如果姓约翰,姓史密斯,姓朱莉,这会匹配,或者如果姓约翰,姓朱莉,姓史密斯,这也会匹配

我正在编写一个脚本,该脚本将在PHP中完成这一切,并针对每一种可能性运行一个单独的查询。比如
lastname='john julie smith'
firstname='john julie smith'
lastname='johnjulie'和firstname='smith'
etc!对于一个三个单词的名字,有105个查询,我有1700个名字需要处理。对我来说这听起来很不可思议

PHP我相当了解,但我对MySQL不是很在行。是否有一个查询可以尝试匹配多列中的所有单词?即使它只处理一个名称组合(“John,Julie,Smith”或“John,Julie,Smith”)。甚至可以使用正则表达式


这就是我的立场

foreach( $a as $name ) {
    //There's some more stuff up here to prepare the strings,
    //removing &/and, punctuation, making everything lower case...

    $na = explode( " ", $name );

    $divisions = count( $na ) - 1;
    $poss = array();
    for( $i = 0; $i < pow(2, $divisions); $i++ ) {
        $div = str_pad(decbin($i), $divisions, '0', STR_PAD_LEFT);
        $tpa = array();
        $tps = '';
        foreach($na as $nak => $nav) {
            if ( $nak > 0 && substr( $div, $nak - 1, 1 ) ) {
                $tpa[] = $tps;
                $tps = $nav;
            } else {
                $tps = trim( $tps . ' ' . $nav );
            }
        }
        $tpa[] = $tps;
        $poss[] = $tpa;
    }
    foreach( $poss as $possk => $possv ) {
        $count = count( $possv );
        //Here's where I am... 
        //I could use $count and some math to come up with all the possible searches here,
        //But my head is starting to spin as I try to think of how to do that.
    }

    die();
}
最初的想法是迭代数组并创建大量查询。对于[0],将有5个查询:

... WHERE firstname = 'john julie smith';
... WHERE lastname = 'john julie smith';
... WHERE spousename = 'john julie smith';
... WHERE title = 'john julie smith';
... WHERE suffix = 'john julie smith';
但对于[1],将有20个查询:

... WHERE firstname = 'john julie' AND lastname = 'smith';
... WHERE firstname = 'john julie' AND spousename = 'smith';
... WHERE firstname = 'john julie' AND title = 'smith';
... WHERE firstname = 'john julie' AND lastname = 'smith';
... WHERE firstname = 'john julie' AND suffix = 'smith';
... WHERE lastname = 'john julie' AND firstname = 'smith';
... WHERE lastname = 'john julie' AND spousename = 'smith';
... WHERE lastname = 'john julie' AND title = 'smith';
... WHERE lastname = 'john julie' AND lastname = 'smith';
... WHERE lastname = 'john julie' AND suffix = 'smith';
//and on and on
对于[3],将有60个查询!以这个速度,我看到170000多个查询


一定有更好的方法…

将1700个名称加载到MySQL中的表中

那么,我认为下面的方法会有所帮助。在字段中查找匹配项,并按匹配项最多的行排序。这不是100%完美的,我怀疑这会有点帮助。查询是:

select n.name, t.*,
       (n.name like concat('%', firstname, '%') +
        n.name like concat('%', lastname, '%') +
        n.name like concat('%', suffix, '%') +
        n.name like concat('%', spousename, '%')
       ) as NumMatches
from table t join
     names n
     on n.name like concat('%', firstname, '%') or
        n.name like concat('%', lastname, '%') or
        n.name like concat('%', suffix, '%') or
        n.name like concat('%', spousename, '%')
group by t.firstname, t.lastname, t.suffix, t.spousename, n.name
order by NumMatches;
编辑:

我第一次忽略了这一点,但是您可以计算每个
名称中的单词数和匹配数。将本条款置于下单人
之前:

having NumMatches = length(n.name) - length(replace(n.n, ' ', '')
这仍然不是完美的,因为相同的名称可以出现在多个字段中。在实践中,它应该工作得很好。如果你想变得更迂腐,你可以这样做:

having concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(n.name, ' ', 1), '%') and
       concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(substring_index(n.name, ' ', 2), ' ', -1), '%') and
       concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(substring_index(n.name, ' ', 3), ' ', -1), '%') and
       concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(substring_index(n.name, ' ', 4), ' ', -1), '%')

这将独立测试每个名称。

我添加了“我所做的”。它很毛茸茸的,而我只走了一半。我希望能有一个更精简的方法,并且会很感激所有的想法。当人们仔细研究每个条目,并将其与现有条目进行比较时,这可能会有所帮助,但似乎没有办法确保
n.name
中的所有单词都匹配。我想在发送一个真实的人通过他们来查看“匹配”是否真的匹配之前,通过编程消除其中的大多数匹配。这是好东西,特别感谢concat的想法。当我有时间再做这个项目的时候,我会参考这个,如果你的答案行得通,我会“接受”你的答案。再次感谢!
having concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(n.name, ' ', 1), '%') and
       concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(substring_index(n.name, ' ', 2), ' ', -1), '%') and
       concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(substring_index(n.name, ' ', 3), ' ', -1), '%') and
       concat_ws(':', firstname, lastname, suffice, spousename) like concat('%', substring_index(substring_index(n.name, ' ', 4), ' ', -1), '%')