2011-10-06 116 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