忽略来自foreach循环的重复结果迭代mysql查询

时间:2011-10-06 12:24:38

标签: php mysql arrays 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);

抱歉,如果这是一团糟..我自己从互联网上教...它确实有效,但在同一记录中返回多个变量的重复...

2 个答案:

答案 0 :(得分:0)

  

SELECT * FROM foo WHERE Building LIKE ...&amp;&amp; Neighborhood = ....   &安培;&安培; View喜欢...&amp;&amp; Condition喜欢...&amp;&amp; Frontage喜欢......   Listprice BETWEEN ...&amp;&amp; Year_Built&gt; = ...&amp;&amp; Status LIKE ......

如果我没错,这个查询表明你有一个包含所有上述属性的表。

至少查看多值属性的气味。如果在同一个表中找到它,那么这是冗余数据的一个非常经典的例子。因此,如果你有一个房子的三个视图,你最终将存储3个同一建筑物的记录。

这里出现了一些问题:

  1. 你如何可靠地识别,如何正确。
  2. 如果您有2000个房子,其中一半有2个视图,您将会结束 在同一张表中有1000多条记录
  3. 删除或更新
  4. 有多容易
  5. 查询的一致性(我认为这是您的问题所在) 等
  6. 如果这是真的那么99%你在工作环境中不会改变任何东西,但是知道系统中的流量是多么好,这样你就可以采取措施。

    在理想的情况下,您处于构建阶段,仍在开发中,然后对于多个值的每个属性,您需要使用构建表的外键将字段自己传输到新表。

    然后,如果用户选择多个视图,您将查询如下:

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

    这个查询不能带来多条记录,因为没有这样的东西, 每个建筑物只定义一次,标识清晰(主键)为 正常化的结果,在建筑表中!另一方面,视图中的多个记录将有助于捕获记录(如果有任何或所有视图 匹配)。

    最后一件事就是看到4个循环在一起通常会强烈警告代码需要认真优化!

    我也同意您现在可以选择不同的颜色!

答案 1 :(得分:0)

如果您希望将当前设计与存储在单个单元格中的视图保持一致,那么您可以执行某些操作。虽然我不建议我在下面给出一个例子,因为你已经设计了这样的项目。

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

我假设视图存储在单个单元格中,空格分隔,并且如果视图由多个单词组成 - 位于其间,例如City-Center。

研究此示例,看看是否可以根据需要进行调整:

<?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查询!!

如果仍有任何问题,请考虑提供有关数据库架构和一些基本描述的详细信息希望这可以提供帮助!