2015-04-01 165 views
1

我想根据多选框中的值筛选一个mysql表,以便返回所有已选择值的结果。举例来说,这是我的多选框:基于多选框筛选mysql结果

<select name="gift[]" id="gift" multiple="multiple" onchange="change()"> 
      <option value="him">Him</option> 
      <option value="her">Her</option> 
      <option value="kids">Kids</option> 
      <option value="teens">Teens</option> 
      <option value="mothersday">Mothers Day</option> 
      <option value="fathersday">Fathers Day</option> 
      <option value="valentines">Valentines Day</option> 
      <option value="gadgets">Gadgets</option> 
      <option value="secretsanta">Secret Santa</option> 
</select> 

如果用户选择“他”和“小工具”,它应该从MySQL表或者用“他”或者它的“小玩意”返回所有结果。

mysql表中的每个产品的数据都以字符串的形式存储在单个列中(例如,根据'gift'列可能会说他,她,孩子,小工具或其他行可能是她的小工具。上面的例子我希望它返回两行)。

结果由AJAX返回,我曾尝试使用WHERE IN子句,但无法得到它working.Here是我的代码(HTML选择框上面已经):

AJAX 注:不是完整的代码为简单起见

function change(){ 
var giftarray = new Array(); 
$.each($("#gift option:selected"), function(){    
     giftarray.push($(this).val()); 
}); 

var gift = "'" + giftarray.join("','") + "'"; 

if (window.XMLHttpRequest) 
{// code for IE7+, Firefox, Chrome, Opera, Safari 
xmlhttp=new XMLHttpRequest(); 
} 
else 
{// code for IE6, IE5 
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
} 

xmlhttp.onreadystatechange=function() 
{ 
if (xmlhttp.readyState==4 && xmlhttp.status==200) 
{ 
document.getElementById("product").innerHTML=xmlhttp.responseText; 
} 
} 

var url="results.php" 
url=url+"&gift="+gift; 

xmlhttp.open("GET",url,true); 
xmlhttp.send(); 
} 

Results.PHP 注:为简单起见,

$gift=$_GET['gift']; 
$gift=str_replace("\\","",$gift); 
$sql= "SELECT * FROM $productstable WHERE gift IN ($gift)"; 
$result = mysql_query($sql) or die ('Unable to run query:'.mysql_error()); 
while($item = mysql_fetch_array($result)) 
{ 
code to view products here 
} 
<? } mysql_close() ?> 
不完整的代码

MySQL表和数据注:我只显示了两行的礼品列,ID和数据(希望这是确定)

CREATE TABLE `products` (
`id` int(255) NOT NULL AUTO_INCREMENT, 
`gift` varchar(100) NOT NULL, 

PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; 

INSERT INTO `products` VALUES(1,'him,her'); 
INSERT INTO `products` VALUES(2,'him,her,teens,gadgets'); 

这似乎是产品是否具有分配的只有一个值工作它在MySQL表中,但不是当它有多个。从我读过的内容来看,我想我可能会在单个列中存储多个条件时出错,但不知道如何解决该问题。非常感谢。

+1

你可以编辑你的问题,包括你正在使用的数据库表中的一些示例吗? – ydaetskcoR 2015-04-01 10:43:16

+0

仍然使用原生javascript for AJAX?考虑使用jQuery!另外,停止使用不推荐使用的'mysql_ *'函数;使用MySQLi或PDO。 – Raptor 2015-04-01 10:52:12

+0

数据库脚本添加,也感谢猛禽,生病了它改变了。任何想法,为什么它不工作? – Josh 2015-04-01 11:38:41

回答

2

你正在做这个错误的方式。

首先,阅读关于数据库规范化。你必须有3张桌子。

type { id, title } for storing him,her,teens,gadgets as rows with unique id 
product { id, product_title, ...... } for storing products 
product_type {product_id, type_id} to store relation product -> type 

必须发送选项数据数组:

index.php?options[1]=him&options[2]=her&options[3]=kids 

然后在PHP中你获得的是:

$options = $_GET['options']; 

然后你就可以使用建立查询联接:

$q = "SELECT a.id, a.product_title from product a JOIN product_type b ON a.a=b.product_id WHERE b.type_id IN('".implode("','",$options)."')"; 

ps 这只是一个例子。非常不安全。您必须准备好安全声明,验证输入数据,创建正确的索引。你可以在数组中存储带有ID的“type”,但我更喜欢存储在数据库中。

你的例子来自关系数据库设计方面的错误。此外,使用LIKE效率非常低。

+0

谢谢,我知道必须有更合乎逻辑的方法。我试试这个。只需确认,在存储礼品选项的类型表中,礼品是否仍然存储在逗号分隔列表中,还是应该各自具有自己的列?第三张桌子实际上是必要的,还是只有前两张才有可能? – Josh 2015-04-02 09:28:51

+0

礼物选项被存储为行!表格类型将只有2列:标识,标题 – 2015-04-02 09:32:06

0

好吧,所以我找到了一个解决方案,但很确定它不是正确的方式,因为它不是很优雅。任何改进建议都欢迎。我将$ gift变量分解为一个数组,然后使用通配符生成几个OR LIKE语句以进行匹配。看起来,我的多选框中只有9个选项,因为这种方法很快就会变得乏味。

CODE: RESULTS.PHP

$gift=$_GET['gift']; 
$gift=str_replace("\\","",$gift); 
$gift=str_replace("'","%",$gift); 
$gift=explode(",",$gift); 

$sql= "SELECT * 
FROM $productstable 
WHERE gift LIKE '$gift[0]' 
OR gift LIKE '$gift[1]' 
OR gift LIKE '$gift[2]' 
OR gift LIKE '$gift[3]' 
OR gift LIKE '$gift[4]' 
OR gift LIKE '$gift[5]' 
OR gift LIKE '$gift[6]' 
OR gift LIKE '$gift[7]' 
OR gift LIKE '$gift[8]' 
OR gift LIKE '$gift[9]'"; 

$result = mysql_query($sql) or die ('Unable to run query:'.mysql_error()); 
while($item = mysql_fetch_array($result)) 
{ 
code to view products here 
} 
<? } mysql_close() ?> 

不喜欢这种方法在所有真如思想应该做相同的,但只是不可能得到它的工作。这会对速度产生负面影响吗?

也将在稍后使用PDO重新编码。