ricerca basata sulla formula Haversine

Salve, sto realizzando una action di ricerca che ordina dei negozi per distanza in base all’indirizzo di partenza e il raggio di ricerca, ho una tabella vetrina in cui ho inserito tra i vari campi latitudine,longitudine e link_sconto (in realtà è il campo che popolo con il raggio entro cui fare la ricerca) ecc… ora eseguendo la action mi da il seguente errore

CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘<24ORDER BY distanceLIMIT 0,20’ at line 1

questa è la mia action $model->latitudine, $model->longitudine, $model->link_sconto sono i parametri che ricevo dalla view al submit

public function actionRicerca()

{


	&#036;model=new Vetrina('search');


	&#036;model-&gt;unsetAttributes();  // clear any default values


	if(isset(&#036;_POST['Vetrina'])){


		&#036;model-&gt;attributes=&#036;_POST['Vetrina'];


		


		//crea  query


		&#036;connection = Yii::app()-&gt;db;


		&#036;sql = 'SELECT id_vetrina,proprietario,indirizzo,cap,municipio,logo,telefono,sito,descrizione,categoria,sottocategoria,pubblicato,( 3959 * acos( cos( radians('.&#036;model-&gt;latitudine.') ) * cos( radians( latitudine ) ) * cos( radians( longitudine ) - radians('.&#036;model-&gt;longitudine.') ) + sin( radians('.&#036;model-&gt;latitudine.') ) * sin( radians( latitudine ) ) ) ) AS distance FROM vetrina';


		&#036;sql .= 'HAVING distance&lt;'.&#036;model-&gt;link_sconto;


		&#036;sql .= 'ORDER BY distance';


		&#036;sql .= 'LIMIT 0,20';





		


		&#036;command = &#036;connection-&gt;createCommand(&#036;sql);


		&#036;results = &#036;command-&gt;queryAll();


	  	


	&#036;this-&gt;render('index',array(


		'dataProvider'=&gt;&#036;results,


	));


	}else {


	


	&#036;this-&gt;render('ricerca',array(


		'model'=&gt;&#036;model,


	));


	}


}

da quanto ho capito il problema dovrebbe essere nella parte SQL prima di FROM ma dove??? sembra tutto corretto!!!

La prima cosa che ho notato e "24ORDER" e "distanceLIMIT"

le frasi sono incolatte!

Esatto!! hai fatto una grande osservazione!!! era quello il problema lo spazio…

Ora

ammesso che la query dia risultati, la parte di codice che segue è corretta??

$command = $connection->createCommand($sql);

		&#036;results = &#036;command-&gt;queryAll();


	  	


	&#036;this-&gt;render('index',array(


		'results'=&gt;&#036;results,'sql'=&gt;&#036;sql,


	));

poi dalla view ho fatto un test con soli due campi

?php echo foreach( $results as $data ): ?>

<div class="view">

&lt;b&gt;&lt;?php ///echo CHtml::encode(&#036;data-&gt;getAttributeLabel('id_vetrina')); ?&gt;:&lt;/b&gt;


&lt;?php echo CHtml::link(CHtml::encode(&#036;data-&gt;id_vetrina), array('view', 'id'=&gt;&#036;data-&gt;id_vetrina)); ?&gt;


&lt;br /&gt;





&lt;b&gt;&lt;?php //echo CHtml::encode(&#036;data-&gt;getAttributeLabel('proprietario')); ?&gt;:&lt;/b&gt;


&lt;?php echo CHtml::encode(&#036;data-&gt;proprietario); ?&gt;


&lt;br /&gt;





&lt;/div&gt;

<?php endforeach; ?>

ma sembra come se $results non fosse passato alla view! sbaglio qualcosa????

Funziona perfettamente!!! mia culpa!!! nella view sbagliavo il modo di leggere i dati,

foreach( $results as $data ) qui $data è un array e per leggere il contenuto basta fare

<?php echo $data[proprietario]; ?> ecc…

Perche’ non usi un model? Puoi fare tutto benissimo con un CDbCritera, e non rischi di sbagliare a scrivere sql.

Inoltre puoi scrivere le funzioni per la visualizzazione dei dati nel model, lasciando il codice molto piu’ ordinato.

Buona idea, ci vorrei provare, ma con criteria non so come trattare la mega funzione con sin e cos… per il calcolo della vicinanza!!!

sto cercando di vedere come funziona, tanto ho già il model per la tabella "vetrina" su cui ho realizzato un crud…

E’ molto semplice, basta fare:


$criteria= new CDbCriteria;

$criteria->select= "id_vetrina,proprietario,indirizzo,cap,municipio,logo,telefono,sito,descrizione,categoria,sottocategoria,pubblicato,( 3959 * acos( cos( radians('.$model->latitudine.') ) * cos( radians( latitudine ) ) * cos( radians( longitudine ) - radians('.$model->longitudine.') ) + sin( radians('.$model->latitudine.') ) * sin( radians( latitudine ) ) ) ) AS distance";

$criteria->having = ...




Devi anche aggiungere un parametro al model:


public $distance;

Questa cosa la puoi scrivere nella funzione search che trovi nel model, in modo da preparare un CActiveDataProvider con i dati che ti servono.

Cosi’ puoi addirittura usare CGridView o CListView, avere il paging e il sorting gia’ gestito, insomma, tutto piu’ facile.