игнорировать повторяющиеся результаты из цикла foreach, повторяющегося в запросе mysql - PullRequest
0 голосов
/ 06 октября 2011

Я настроил форму множественного выбора для возврата массивов, а затем зациклил их через запрос 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 голосов
/ 08 октября 2011

Если вы хотите сохранить текущий дизайн с видом, хранящимся в одной ячейке, то есть что-то, что вы можете сделать. Хотя я не предлагаю этого, я приведу пример ниже, потому что вы уже разработали свой проект таким образом.

ВНИМАНИЕ: Это пример тестирования, чтобы увидеть основные функции. Это не окончательный код, потому что внедрение 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 не задействован !!

Если проблема остается, рассмотрите подробности схемы БД и некоторое базовое описание. Надеюсь, это поможет!

0 голосов
/ 06 октября 2011

ВЫБРАТЬ * ИЗ foo ГДЕ Building НРАВИТСЯ ... && Neighborhood = .... && View НРАВИТСЯ ... && Condition НРАВИТСЯ ... && Frontage НРАВИТСЯ... Listprice BETWEEN ... && Year_Built> = ... && Status LIKE ...

Если я не ошибаюсь, этот запрос указывает на наличие одной таблицысо всеми вышеперечисленными атрибутами.

Как минимум Просмотр запахов атрибута с несколькими значениями.Если он найден в той же таблице, то это очень классический пример избыточных данных.Таким образом, если у вас есть три вида для дома, вы в конечном итоге будете хранить 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 цикла вместе, обычно является сильным предупреждением о том, что код нуждается в серьезной оптимизации.!

Я также согласен с тем, что на данный момент ваш выбор является отличным!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...