dpvr49226 2017-04-12 14:09
浏览 39
已采纳

使用不同数量的搜索键在数据库中搜索客户

found some other posts, but none of them really helped me (maybe I am too stupid for searching). Even the Similar Questions block while typing this did not help.

Here is my question: I got a mysql database with 4 columns: id, first-name, last-name, city

On a php application I got an input field that queries via AJAX the php script to search the database. This field works if only 1 search term is given, like first-name. As soon I try 2 or 3 search terms I have no idea how to query the db.

Please help me how to query my database (got like 20,000 rows). Some search examples: Thomas Boston Michael Smith New York Doe, Jane Orlando, Michael Expected result are all rows that contain any of those search terms. Best would be to have it ordered by similarity (most terms found first). Using DIFFERENCE() would be nice, too, but my script is in German....

I have read stuff about full text search, but have no idea how to do this.

Here is my current query code (for 1 search term):

$key = $_GET['key'];
//Here will be something to filter all non numbers/letters and change them to a space for $key
$keys = explode(" ",$key); //$keys is not in use yet
$prep_stmt = "
SELECT 
    id, last-name, first-name, city 
FROM 
    customers 
WHERE 
    last-name LIKE concat('%', ? ,'%') OR
    first-name LIKE concat('%', ? ,'%')  OR
    city LIKE concat('%', ? ,'%') 
ORDER BY 
    last-name ASC";
$stmt = $mysqli->prepare($prep_stmt);
$stmt->bind_param('sss', $key, $key, $key);

About security: This code runs in an internal environment. So security is not the biggest priority.

PS: I am not native English, but I tried my best.


Stuff I found, but didn't help:


~~EDIT~~

Stuff I came up with, but didn't work:

$key = trim(preg_replace( '/\s+/', ' ', preg_replace("/[^[:alnum:][:space:]]/u", ' ', $key)));

SELECT
    id, last-name, first-name, city 
FROM
    customers
WHERE
    last-name LIKE concat('%', REPLACE( ? ,' ','%') ,'%') OR
    first-name LIKE concat('%', REPLACE( ? ,' ','%') ,'%') OR
    city LIKE concat('%', REPLACE( ? ,' ','%') ,'%')                
ORDER BY
    name ASC
  • 写回答

2条回答 默认 最新

  • dtnpf35197 2017-04-12 15:32
    关注

    Thanks to Rogier Bruggeman I got an idea how to solve my problem. This is how I solved it:

    $key = $_GET['key'];
    $key = trim(preg_replace( '/\s+/', ' ', preg_replace("/[^[:alnum:][:space:]]/u", ' ', $key)));
    $keys = explode(" ",$key);
    $key_num = count($keys);
    if(NOT RELEVANT == RELEVANT){
        NOT RELEVANT
    } else {
        //prepare statement
        $prep_stmt = "SELECT id  FROM customers WHERE ";
        if($key_num == 1){
            $prep_stmt .= "
                lastname LIKE ? OR
                firstame LIKE ? OR
                zip LIKE ? OR
                city LIKE ?
            ORDER BY
                lastname ASC";
            $stmt = $mysqli->prepare($prep_stmt);
            $key = '%' . $key . '%';
            $stmt->bind_param('ssss', $key, $key, $key, $key);
        } else {
            $p = 0;
            foreach($keys as $v){
                if($p <> 0){
                    $prep_stmt .= " AND ";
                }
                $prep_stmt .= "(lastname LIKE ? OR firstname LIKE ? OR zip LIKE ? OR city LIKE ? )";
                $p++;
            }
            $prep_stmt .= " ORDER BY name ASC";
            $stmt = $mysqli->prepare($prep_stmt);
            switch($key_num){
                case 2:
                    $keys[0] = '%' . $keys[0] . '%';
                    $keys[1] = '%' . $keys[1] . '%';
                    $stmt->bind_param('ssssssss', $keys[0], $keys[0], $keys[0], $keys[0], $keys[1], $keys[1], $keys[1], $keys[1]);
                    break;
                case 3:
                    $keys[0] = '%' . $keys[0] . '%';
                    $keys[1] = '%' . $keys[1] . '%';
                    $keys[2] = '%' . $keys[2] . '%';
                    $stmt->bind_param('ssssssssssss', $keys[0], $keys[0], $keys[0], $keys[0], $keys[1], $keys[1], $keys[1], $keys[1], $keys[2], $keys[2], $keys[2], $keys[2]);
                    break;
                case 4:
                    $keys[0] = '%' . $keys[0] . '%';
                    $keys[1] = '%' . $keys[1] . '%';
                    $keys[2] = '%' . $keys[2] . '%';
                    $keys[3] = '%' . $keys[3] . '%';
                    $stmt->bind_param('ssssssssssssssss', $keys[0], $keys[0], $keys[0], $keys[0], $keys[1], $keys[1], $keys[1], $keys[1], $keys[2], $keys[2], $keys[2], $keys[2], $keys[3], $keys[3], $keys[3], $keys[3]);
                    break;
                case 5:
                    $keys[0] = '%' . $keys[0] . '%';
                    $keys[1] = '%' . $keys[1] . '%';
                    $keys[2] = '%' . $keys[2] . '%';
                    $keys[3] = '%' . $keys[3] . '%';
                    $keys[4] = '%' . $keys[4] . '%';
                    $stmt->bind_param('ssssssssssssssssssss', $keys[0], $keys[0], $keys[0], $keys[0], $keys[1], $keys[1], $keys[1], $keys[1], $keys[2], $keys[2], $keys[2], $keys[2], $keys[3], $keys[3], $keys[3], $keys[3], $keys[4], $keys[4], $keys[4], $keys[4]);
                    break;
                case 6:
                    $keys[0] = '%' . $keys[0] . '%';
                    $keys[1] = '%' . $keys[1] . '%';
                    $keys[2] = '%' . $keys[2] . '%';
                    $keys[3] = '%' . $keys[3] . '%';
                    $keys[4] = '%' . $keys[4] . '%';
                    $keys[5] = '%' . $keys[5] . '%';
                    $stmt->bind_param('ssssssssssssssssssssssss', $keys[0], $keys[0], $keys[0], $keys[0], $keys[1], $keys[1], $keys[1], $keys[1], $keys[2], $keys[2], $keys[2], $keys[2], $keys[3], $keys[3], $keys[3], $keys[3], $keys[4], $keys[4], $keys[4], $keys[4], $keys[5], $keys[5], $keys[5], $keys[5]);
                    break;
                default:
                    $stmt = "SELECT id FROM customer WHERE 1 LIKE 2";
                    $stmt = $mysqli->prepare($prep_stmt);
            }
    
        }
    

    It is kind of dirty, but it works. Really dirty is my default in the switch

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么