2011-10-06 123 views
0

我成立了一个多选的形式返回数组,然后循环他们通过MySQL查询返回的结果忽略foreach循环通过MySQL查询

迭代重复结果

我不想重复的结果,如果用户选择多个选项和那些 选项出现在一个记录

例如用户选择三个不同的“意见”和一个酒店有三个观点,我不希望出现这种情况显示在结果三次......谢谢你,如果你能帮助

require ('db.php'); 

    $N = $_GET['Neigh']; 
    $V = $_GET['view']; 
    $C = $_GET['Con']; 
    $F = $_GET['front']; 
$minPrice = $_GET['minprice']; 
$maxPrice = $_GET['maxprice']; 
$Year = $_GET['YearBuilt']; 



    foreach($N as $Nvalue){ 
    if ($Nvalue != "\n\r" || $Nvalue != "" || $Nvalue !=NULL) 
    foreach($C as $Cvalue){ 
    foreach($F as $Fvalue){ 
    foreach($V as $Vvalue){ 

    $query="SELECT * 
    FROM `foo` 
    WHERE `Building` LIKE '%{$Bvalue}%' && `Neigh` = '{$Nvalue}' && `View` 
    LIKE '%{$Vvalue}%' && `Con` LIKE '%{$Cvalue}%' 
    && `front` LIKE '%{$Fvalue}%' && `Listprice` BETWEEN '{$minprice}' AND '{$maxprice}' 
    && `Year_Built` >= '{$Year}' && `Status` LIKE '%Active%' GROUP BY `MLS` 
    ORDER BY `Neigh`, `price`, `tmk` ASC"; 

    $result=mysql_query($query) or die('Query failed: ' . mysql_error() . "<br />\n $query"); ; 

    $num=mysql_num_rows($result); 

对不起,如果这是一个烂摊子..即时通讯自我从互联网上教..它的工作,但返回在同一记录多个变量重复...

+0

尝试使用distinct:http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html – JellyBelly

+0

SQL注入警告,请阅读:http://stackoverflow.com/questions/332365/xkcd-sql-injection-please-explain – Johan

回答

0

如果你想保持目前的设计与存储在单个单元格观点,那么有什么可以做。虽然我不建议它,但我会在下面举一个例子,因为您已经设计好了这样的项目。

注意:这是一个测试示例,查看基本功能。这不是最终的代码导致sql注入和其他事情不考虑。

我做到这一点的看法是存储在单个单元格,空间分隔的假设,如果一个视图由多于一个字 - 是发生在之间,例如城市中心。

研究这个例子,看看你可以把它调整到您的需要:

<?PHP 
echo '<pre>'; 

//mysql connect 
mysql_connect('localhost', 'root',''); 
mysql_select_db("test"); 
//add some tsting data 
addTestingData(); 

//build sql from user input via $_GET 
$sqlConditions = builtSql();//build sql conditions 
$sql = 'select * from `building` where '.$sqlConditions;//build final sql 

//get data from mysql 
$result = mysql_query($sql) ; 
while($row= mysql_fetch_row($result)) 
    print_r($row); 

///////////////end//////////////////////////////////////////// 

function addTestingData() 
{ 

mysql_query("DROP TABLE IF EXISTS `Building`"); 
    mysql_query(" 
CREATE TABLE `Building` (
    `building_uniqueid` MEDIUMINT UNSIGNED NOT NULL , 
    `building_street` VARCHAR(30) NOT NULL, 
    `building_street_nr` VARCHAR(7) NOT NULL, 
    `building_neighborhood` VARCHAR(30) NOT NULL, 
    `building_view` VARCHAR(250) NOT NULL, 
    `building_condition` VARCHAR(150) NOT NULL, 
    `building_frontage` VARCHAR(30) NOT NULL, 
    `building_listprice` float NOT NULL, 
    `building_year` smallint not null, 
    `bsnss_comments` VARCHAR(255), 
    PRIMARY KEY (`building_uniqueid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; 
"); 

    mysql_query(' 
insert into `building` (`building_uniqueid`,`building_street`,`building_street_nr`, 
`building_neighborhood`,`building_view`,`building_condition`,`building_frontage`, 
`building_listprice`,`building_year`,`bsnss_comments`) values 
("1","street1","strnr1","neighb1","Mountain Ocean Lake Park City-Center", 
"good","frontage1","500.3","1990","good building") 
'); 

    mysql_query(' 
insert into `building` (`building_uniqueid`,`building_street`,`building_street_nr`, 
`building_neighborhood`,`building_view`,`building_condition`,`building_frontage`, 
`building_listprice`,`building_year`,`bsnss_comments`) values 
("id2","street1","strnr1","neighb2","River Ocean Lake Park City-Center", 
"very good","frontage1","800.5","1991","good building") 
') or die(mysql_error()); 

    mysql_query(' 
insert into `building` (`building_uniqueid`,`building_street`,`building_street_nr`, 
`building_neighborhood`,`building_view`,`building_condition`,`building_frontage`, 
`building_listprice`,`building_year`,`bsnss_comments`) values 
("3","street3","strnr3","neighb1","Ocean Park City-Center", 
"fantastic","frontage77","600.7","1994","good building") 
'); 

    mysql_query(' 
insert into `building` (`building_uniqueid`,`building_street`,`building_street_nr`, 
`building_neighborhood`,`building_view`,`building_condition`,`building_frontage`, 
`building_listprice`,`building_year`,`bsnss_comments`) values 
("4","street4","strnr4","neighb1","Ocean Park Mountain City-Center", 
"good","frontage1","500.23","1994","good") 
'); 

    $_GET['Neighborhood']=array('neighb1'); 
    $_GET['View']=Array('Mountain','River', 'City Center'); 
    $_GET['Condition']=array('good','very good'); 
    $_GET['Frontage']=array('frontage77','frontage1'); 
    $_GET['minPrice']='500'; 
    $_GET['maxPrice']='600'; 
    $_GET['minYear']='1990'; 
    $_GET['maxYear']='1995'; 



} 



function builtSql() 
{ 

    $sqlBuild = '('; 

//formate sql for Neighborhood 
foreach($_GET['Neighborhood'] as $value) 
    $sqlBuild .=' `building_neighborhood` = \''.$value.'\' or '; 
    $sqlBuild=removeLastOr($sqlBuild); 
    $sqlBuild.=') and ('; 

//formate sql for View 
foreach($_GET['View'] as $value) 
    $sqlBuild .=' `building_view` LIKE \'%'.str_replace(" ", "-",$value).'%\' or '; 
    $sqlBuild=removeLastOr($sqlBuild); 
    $sqlBuild.=') and ('; 

//formate sql for Condition 
foreach($_GET['Condition'] as $value) 
    $sqlBuild .=' `building_condition` = \''.$value.'\' or '; 
    $sqlBuild=removeLastOr($sqlBuild); 
    $sqlBuild.=') and ('; 

//formate sql for Frontage 
foreach($_GET['Frontage'] as $value) 
    $sqlBuild .=' `building_frontage` = \''.$value.'\' or '; 
    $sqlBuild=removeLastOr($sqlBuild); 
    $sqlBuild.=') and ('; 

//formate sql for Price 
$sqlBuild.= 
' `building_listprice` BETWEEN \''.$_GET['minPrice'].'\' and \''.$_GET['maxPrice'].'\' '; 
    $sqlBuild=removeLastOr($sqlBuild); 
    $sqlBuild.=') and ('; 

//formate sql for Year 
$sqlBuild.= 
' `building_year` BETWEEN \''.$_GET['minYear'].'\' and \''.$_GET['maxYear'].'\' '; 
    $sqlBuild.=') '; 

return $sqlBuild; 
} 

function removeLastOr($str) 
{ 
    $tmp=substr($str ,0,(strlen($str)-2)); 
    return $tmp=substr($str ,0,(strlen($str)-3)); 
} 

?> 

虽然你看到一些foreach循环,没有必要担心,因为它们运行包含用户数据的小一阳指,所以考虑他们运行速度超快,因为没有涉及mysql查询!

如果有任何问题仍然考虑在DB模式和一些基本的描述透露更多细节。希望这可以帮助!

+0

非常感谢你很多..我现在要试试这个.. @Melsi –

+0

即时通讯很多错误..我解决一个,然后我再弄那么我就要回来以后它今晚 –

+0

我建议你先在自己的运行代码,**是没有错误的**,这是我已经把那里的一切的原因,为了让它立即独立运行,只需将mysql连接的正确信息。在你完全理解它是如何工作的之前,不要着手将它合并到你的应用程序中。如果你理解得很好,那么将它合并到你的应用程序应该没问题。最后,你现在的数据库模式是什么,得到一个SQL转储,(现在太晚了,睡觉) – Melsi

0

SELECT * FROM foo WHERE Building LIKE ...... & & Neighborhood = .... & & View像... & & Condition像... & & Frontage像... Listprice BETWEEN ... & & Year_Built> = ... & & Status像...

如果我没看错的这个查询表明您具有上述所有属性的单个表。

至少查看多值属性的气味。如果它在同一个表中找到,那么它就是冗余数据的一个非常经典的例子。所以,如果你有三个房子的意见,你最终会为同一栋建筑物存储3条记录。

一些问题在这里出现:

  1. 如何值得信赖你能识别是,如何正确的。
  2. 如果你有2000米的房屋和其中一半有2次你最终会 1000多个记录在同一个表
  3. 有多容易删除或更新
  4. 如何一致是查询(我想这是你的问题属于) 等

如果这是真的,那么99%你是不会改变在工作环境中进行任何操作,但是最好知道系统中有什么流量,以便采取措施。

在,你是在建设阶段,仍处于开发阶段然后你就需要到外地与外键建表转移到新表上自己的多个值的每一个属性的理想情况。

然后,如果用户将选择多个视图,你会质疑这样的:

select some_fields 
from building 
left join on views 
where view = view1 or view2 etc 

该查询不能把多个记录,因为没有这样的事情, 每一个建筑只被定义一次,有明显标识(主键)作为 正常化的结果,在建筑物表中!另一方面,视图中的多个记录将帮助记录一个记录(如果任何或全部视图匹配)。

而且看到4路一起最后一件事,通常这是一个强烈的警告,该代码需要认真优化!

我也同意,不同的是你的选项吧!

+0

非常感谢。我试图使用不同的,但我想带来不同的记录回1列一个独特的ID,但不同的不会让我把我需要填写我的结果表下面的所有信息。 \t 我会尝试多表建议。谢谢 –

+0

只是为了澄清..所有的意见都存储在我的表中,像这样的山,海洋,码头在一行..即时通讯不知道如果加入会有所作为,但我会尝试... @Melsi –

+0

虽然你选择了什么字段来取回字段值,并且还要记住字段值的条件,因为没有像独特的字段那样的东西。这是因为我们在行上进行查询,我们的对象始终是行,所以当你想到不同的时候,你必须考虑记录行。考虑显示一个sql dump或一些关于你的表的描述以及一些商业规则(你知道什么是你的数据库应该这样做),将会有很大帮助,否则继续处理有问题的数据库模式并不是很有帮助。 – Melsi