简体   繁体   English

如果找不到精确的搜索词,使SQL查找最接近的结果?

[英]Making SQL find the nearest result if it can't find the exact search term?

I am creating a multi-form search box that searches a Meat packaging database. 我正在创建一个搜索肉类包装数据库的多形式搜索框。 The search works only if users are specific, I want them to be able to search the database without having to choose a specific option. 搜索仅在特定用户时才有效,我希望他们能够搜索数据库而不必选择特定选项。 Three of the form boxes are for users to search width, height and depth all numerical values, but they only return results if the user is exact with the sizes. 用户可以使用三个表单框来搜索宽度,高度和深度的所有数值,但是只有在用户使用尺寸正确时,它们才返回结果。 I want the search to be able to return the nearest value if it cannot find an exact match to the one entered by the user. 我希望搜索能够返回最接近的值(如果它找不到与用户输入的值完全匹配的值)。

Such as: 如:

If user enters "252" in the width box, it will currently return "No searches found" But there is a "251" in the database. 如果用户在宽度框中输入“ 252”,则当前将返回“找不到搜索”,但是数据库中存在“ 251”。 So if the user types in "252" the SQL query then automatically looks for the nearest sizes and then displays in theory "251". 因此,如果用户键入“ 252”,则SQL查询将自动查找最接近的大小,然后在理论上显示“ 251”。

Here is the HTML and PHP: 这是HTML和PHP:

<body>

    <form action="form3.php" method="post"> 
      <label for ="description">Description:</label>
      <input type="text" name="descrip" /><br />

      <label for ="trayheight">Trayheight:</label>
      <input type="text" name="height" /> <br /> 

      <label for ="traywidth">Traywidth:</label>
      <input type="text" name="width" /> <br />

      <label for ="traydepth">Traydepth:</label>
      <input type="text" name="depth" /> <br />

      <label for="trayrange">Trayrange: </label>
                <select name="trayrange">
                    <option value=""></option>

                    <option value="BBQ">BBQ</option>

                    <option value="Dessert">Dessert</option>

                    <option value="Display">Display</option>

                    <option value="Meat">Meat</option>   

                    <option value="Microwave">Microwave</option>

                    <option value="Party">Party</option>

                    <option value="Salad/Wet Pasta">Salad/Wet Pasta</option>

                    <option value="Snacks">Snacks</option>

                    <option value="Standard">Standard</option>

                </select>

        <label for ="traytype">Traytype: </label> 
            <select name="traytype">
                    <option value=""></option>

                <option value="Open">Open</option>

            <option value="Cavitised">Cavitised</option>

                    <option value="Lid">Lid</option>

                    <option value="Tray">Tray</option>

                    <option value="Coallition">Coallition</option>

                    <option value="Bowl">Bowl</option>

                    <option value="Hinge pack">Open</option>

                    <option value="Pot">Pot</option>

                    <option value="Base & Lid">Base and Lid</option>

                    <option value="Rectangular">Rectangular</option>

                    <option value="Specalist">Specialist</option>
            </select><br />

        <label for="trayshape">Trayshape: </label>
            <select name="trayshape">
                    <option value=""></option>

            <option value="Rectangular">Rectangular</option>

                <option value="Oval">Oval</option>

                <option value="Square">Square</option>

                    <option value="Insert">Insert</option>

                    <option value="Round">Round</option>

                    <option value="Open">Open</option>
            </select><br />

        <input type="submit" value="Submit" /> 
    </form> 

    </body>

And the PHP: 和PHP:

   <body>

 <?php
    $con = mysql_connect ("localhost", "root", "");
           mysql_select_db ("delyn_db", $con);

    if (!$con)
        { 
         die ("Could not connect: " . mysql_error());
        }

            $descrip = mysql_real_escape_string($_POST['descrip']); 
            $height  = mysql_real_escape_string($_POST['height']);
            $width   = mysql_real_escape_string($_POST['width']);
            $depth   = mysql_real_escape_string($_POST['depth']);

            $varRange = mysql_real_escape_string($_POST['trayrange']);
            $varType  = mysql_real_escape_string($_POST['traytype']);
            $varShape = mysql_real_escape_string($_POST['trayshape']);
            $varImage = mysql_real_escape_string($_POST['imagename']);

            $sql = "SELECT * FROM delyn WHERE 
                        description LIKE '%".$descrip."%' 
                    AND trayheight LIKE '%".$height."%' 
                    AND traywidth LIKE '%".$width."%' 
                    AND traydepth LIKE '%".$depth."%' 
                    AND trayrange LIKE '%".$varRange."%' 
                    AND traytype LIKE '%".$varType."%' 
                    AND trayshape LIKE '%".$varShape."%' ";


            $r_query = mysql_query($sql);

                    while ($row = mysql_fetch_array($r_query))
                { 
                echo '<br /> Tool Code:   '. $row['toolcode'];
                echo '<br /> Description: '. $row['description']; 
                echo '<br /> Tray range:  '. $row['trayrange']; 
                echo '<br /> Tray type:   '. $row['traytype'];
                echo '<br /> Tray size:   '. $row['traysize']; 
                echo '<br /> Tray shape:  '. $row['trayshape'];  
                    echo '<br /> <img src="   '. $row['imagename'] . '"
                                    width="200" length="100">' . '<br />' . '<br />';  
                    }

                if (mysql_num_rows($r_query) <= 0){
                    echo 'No results match your search, please try
                                                  again';
                                  }
        ?>
                </body>

If anyone could help that would be great, thanks in advance :) 如果有人可以帮助,那就太好了,在此先感谢:)

EDIT: 编辑:

   <body>
        $scope = 20;
                $width_min = $width - $scope;
                $width_max = $width + $scope;
                $depth_min = $depth - $scope;
                $depth_max = $depth + $scope;
                $height_min = $height - $scope;
                $height_max = $height + $scope;

            $sql = "SELECT * FROM delyn WHERE 
                        description LIKE '%".$descrip."%' 
                    AND traywidth LIKE '%".$width."%'   
                    AND traydepth LIKE '%".$depth."%' 
                    AND trayheight LIKE '%".$height."%'
                    AND trayrange LIKE '%".$varRange."%' 
                    AND traytype LIKE '%".$varType."%' 
                    AND trayshape LIKE '%".$varShape."%'";

                if ($row = 0) {
            $sql = "SELECT * FROM delyn WHERE 
                        description LIKE '%".$descrip."%' 
                    AND (traywidth BETWEEN ".$width_min." AND ".$width_max.")  
                    AND (traydepth BETWEEN ".$depth_min." AND ".$depth_max.")  
                    AND (trayheight BETWEEN ".$height_min." AND ".$height_max.")  
                    AND trayrange LIKE '%".$varRange."%' 
                    AND traytype LIKE '%".$varType."%' 
                    AND trayshape LIKE '%".$varShape."%'";
                }
    <body>

Instead of going with a fixed "upper" and "lower" margin, you can sort a list of your entries based upon an absolute calculation between the traywidth in your table and the inputted width by the user. 您可以根据表中纸盘宽度和用户输入的宽度之间的绝对计算,对条目列表进行排序,而不必使用固定的“上”和“下”边距。 Something like this: 像这样:

select d.*, abs(d.traywidth - USER_SEARCH_INPUTTED_WIDTH) as WIDTH_ABS from delyn d order by WIDTH_ABS limit 20;

This will give you a list of nearby traywidths based upon the "USER_SEARCH_INPUTTED_WIDTH", for instance 252 as relative "distances" from what the user is after and what entries the database actually has. 这将基于“ USER_SEARCH_INPUTTED_WIDTH”为您提供附近的纸盘宽度列表,例如252作为与用户所追求的相对距离以及数据库实际拥有的条目的相对“距离”。

Note: all columns you're allowing search in/for needs to be signed otherwise you'll end up with funky results (due to abs). 注意:您允许在其中进行搜索的所有列都必须签名,否则您将得到时髦的结果(由于abs)。

您可以使用SQL BETWEEN运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM