现在我的数据库设置类似于以下示例:
id (int(11)) | name (varchar(20)) | food (varchar(20)) | fastfood (varchar(3)) | pricerange (int(11))
1 | McDonalds | American | Yes | 1
2 | Outback | BBQ | No | 2
3 | Mortons | Steakhouse | No | 3
现在我的用户表单设置如下:
<form action="index.php" method="GET" id="sheet">
<select name="name1" id="name1">
<option value="%">No Preference</option>
<option value="outback">Outback</option>
<option value="mcdonalds">McDonalds</option>
<option value="mortons">Mortons</option>
</select>
<select name="food1" id="food1">
<option value="%">No Preference</option>
<option value="american">American</option>
<option value="bbq">BBQ</option>
<option value="steakhouse">Steakhouse</option>
</select>
<select name="fast" id="fast">
<option value="%">No Preference</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<select name="price" id="price">
<option value="%">No Preference</option>
<option value="1">Cheap</option>
<option value="2">Middle Ground</option>
<option value="3">Expensive</option>
</select>
<input type="submit" value="Submit" id="submit"></input>
<input type="clear" value="Clear" id="Clear"<input>
</form>
现在当我运行以下查询时,如果不是所有字段都匹配,我将得不到任何结果。当我有int
s&amp;时,如何根据最佳匹配操作查询以显示结果?涉及varchar
?
$query = "SELECT * FROM .$usertable
WHERE $name LIKE '$name' AND
$food LIKE '$food1' AND
$fastfood LIKE '$fast' AND
$pricerange LIKE '$price' ";
全文搜索因INT而无效,“OR”不会根据最佳匹配显示结果。假设用户选择了4个选项中的3个,例如:BBQ | Yes | 2
现在,在这种情况下最好的匹配是Outback
,但是因为它也试图匹配快餐,它将不会返回任何结果。如果有更多的选择,它会变得更加复杂。
如果有人能够解决这个问题的解决方案,我将非常感激。
答案 0 :(得分:3)
首先你需要解析那些整数。这些功能可以帮助您:
http://php.net/manual/en/function.intval.php
http://es.php.net/manual/en/function.trim.php
其次,您可能会操纵您的查询,因此整数就像$pricerange <= $price order by $pricerange desc
(此查询首先会为您提供从下方开始的具有更接近价格范围的项目。您可以将其与具有最接近价格范围的其他项目链接,从左上角开始,或者选择从上方或后方选择如果没有匹配。这只是一个中途解决方案,但它有效,许多搜索算法实现了类似的东西。如果你挤压你的大脑,你可能会找到更接近你想要的东西,将查询链接到JOIN
,{{1 },UNION
等。查看mysql manual)
第三,您也可以使用LIMIT
.. JOIN
为搜索添加标准。看看this(如果您不知道如何使用加入,this)
最后,我建议你熟悉PDO。这是在PHP中执行正确数据库查询的最佳方式。
答案 1 :(得分:2)
这实际上不是查询语法的问题。这里的问题是为您的应用程序定义您认为“最佳匹配”。对于这样的函数没有直接的最佳匹配:您需要自己定义它。完成后,您可以继续实施它。
作为一个简单示例,您可以将“最佳匹配”定义为尽可能多的显式查询参数匹配,并且int值参数尽可能接近。然后,您可以计算每场比赛的“得分”,并按此排序。
所以假设搜索是food=BBQ, fastfood=Yes, price=2
。您的查询可能如下所示:
SELECT *,
SUM(
food=:food, -- if food matches, add one to score
fastfood=:fastfood, -- if fastfood matches, add one to score
-- finally, add 2 for an exact price match, 1 for off-by-one price match,
-- 0 for off-by-two matches, etc
(SELECT MAX(price)-1 from foods)-ABS(price-:price)
) AS score
FROM foods ORDER BY score DESC
您可以通过调整添加到分数的数量来调整每个匹配的重要程度。此外,您可以决定类别之间是否存在不同的“距离”。例如,也许“牛排餐厅”更像是“烧烤”而非“美国”,所以牛排餐厅应该得分更高。
这是一种简单的方法,但由于您需要计算每一行的分数,因此效率很低。您可以通过多个查询加快速度:首先查找完全匹配;如果找不到,请计算部分匹配的所有行的分数。只有当仍然没有找到任何内容时,才会回到总表搜索中。
SELECT * FROM foods WHERE food=:food AND fastfood=:fastfood AND price=:price;
-- if no matches then:
SELECT *, SUM(food=:food, fastfood=:fastfood, (SELECT MAX(price)-1 from foods)-ABS(price-:price)) AS score
WHERE food=:food OR fastfood=:fastfood OR price=:price ORDER BY score DESC
答案 2 :(得分:1)
如果您使用的是MySQL,请尝试“匹配”指令! 并使用“OR”而不是“AND”! (匹配是我认为最好的方式)
答案 3 :(得分:1)
嗯,MySQL数据库的设计并没有考虑到这一点。它应该实际上回报你对它的要求,而不是为你做猜测。
不幸的是,这意味着您需要在代码中实现此逻辑。搜索完整匹配,如果不起作用,请搜索某些项匹配的情况。
作为设计师,比赛的相关性将取决于你。
这并不是说你不能把复杂的查询放在一起来获取你所追求的数据,你只需要构建那个逻辑(也许是通过对各种SELECT语句的结果进行UNIONS)。