Query Su Due Tabelle


(Giuliano Ingrosso) #1

Ciao ragazzi,

ho un problema sulla visualizzazione due dati provenienti da una "LEFT OUTER JOIN".

mi spiego meglio.

ho una tabella anagrafica e una smi

devo recuperare tutti i campi della prima e i campi della seconda se esistono

allora… ho pensato di agire sul model in questa maniera :




	public function searchsmi()

	{

		$criteria=new CDbCriteria;

		$criteria->select = "t.codicefiscale, t.nome, t.datadinascita, t.cognome, t.dataultimasmi AS dataultimasmi, t.id_anagrafica,  smi.idsmi as idsmi, [b]smi.datainvito as datainvito[/b] ";

		$criteria->join = 'LEFT OUTER JOIN smi ON t.id_anagrafica = smi.idanagrafica';		

		$criteria->order='idsmi DESC';		


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		'pagination' => array(  'pageSize'=>Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']),),		

		

		));

	}



nel view ho :





	<?php

	$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'anagrafica-grid',

	'dataProvider'=>$model->searchsmi(),

	'filter'=>$model,


	'columns'=>array(

		'id_anagrafica',

		'cognome',

		'nome',

		'codicefiscale',

		'dataultimasmi',

		'idsmi',

		array(

          	'header'=>'Eta\'',    

                'value'=>' datediff("A", date("j-m-Y",strtotime($data->datadinascita)), date("d-m-Y"))',

		),

		)


));


?>




ora…

idsmi che si trova nella ‘seconda’ tabella lo visualizzo correttamente,

invece non riesco a visualizzare ‘datainvito’ nella view

manca qualcosa?


(Fabrizio Caldarelli) #2

Nel senso che ti da errore e non ti visualizza il valore?


(Giuliano Ingrosso) #3

se inserisco nel view


'datainvito'

mi dice che la proprietà anagrafica.datainvito non esiste.

ho provato ad eseguire la query direttamante su phpmyadmin e funziona correttamente visualizzando anche il campo datainvito.

la cosa che risulta strana è come mai il campo ‘idsmi’ viene visualizzato correttamente.


(St4nny) #4

come mai ci metti questo nella query? (intendo b e /B)




[b]smi.datainvito as datainvito[/b]



nella Gridview hai provato sia con anagrafica.datainvito che datainvito?

hai provato a metterci un public $datainvito nel model?


(Sensorario) #5

Io credo si tratti di formattazione del codice. In verità credo volesse solo mettere in evidenza quella parte di query. Se non fosse stato codice, lo avresti visto così "smi.datainvito as datainvito" ovvero bold.


(Giuliano Ingrosso) #6

scusate ragazzi!!! era solo per mettere in evidenza, ma naturalmente non era incluso nel codice.


(Giuliano Ingrosso) #7

ho una bella notizia.

ho aggiunto nel model di anagrafica




public $datainvito;



e ora tutto funziona correttamente.

anche se non mi è del tutto chiaro. qualcuno mi illumina?

grazie mille


(St4nny) #8

datainvito non è un attributo del Model principale,

smi.datainvito non ti avrebbe dato nessun problema con una relazione impostata nel model principale.

Visto che nel Criteria hai creato la query a mano e quindi il campo ti arrivava come se fosse del model Anagrafica, e immagino che il metodo searchsmi era di Anagrafica, non esisteva nessun attributo datainvito a cui affidare il valore.

Piccola domanda al volo… come mai non hai usato il metodo canonico di yii, di settare la relazione smi

e di recuperare la gridview che ti serviva tramite search()?


(Giuliano Ingrosso) #9

grazie mille, sei molto bravo.

e io un po’ meno ma vediamo se riesco a risponderti in maniera corretta. :unsure:

le due tabelle, anagrafica e smi sono legate da una relazione uno->uno, il mio obiettivo è quello di avere una query con tutti i record della prima e qualora ci fossero gli elementi della seconda. Ecco perchè la LEFT OUTER JOIN


		$criteria->join = 'LEFT OUTER JOIN smi ON t.id_anagrafica = smi.idanagrafica';	

l’ho scritta “ad hoc”.

o avrei dovuto agire sul model di smi




	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			

			'idanagrafica0' => array(self::BELONGS_TO, 'Anagrafica', 'idanagrafica'),

			

		);

	}




(St4nny) #10

ma si figurati… ci son solo capitato prima di te ;)

io nel model Anagrafica avrei impostato:




  public function relations()

        {

                // NOTE: you may need to adjust the relation name and the related

                // class name for the relations automatically generated below.

                return array(

                 //relazione 1 a 1 su Model Smi dove anagrafica_id rappresenta la chiave esterna in Smi riferita alla pk di Anagrafica (di solito l'id) se le tabelle le hai organizzate in questa maniera

                     'smi' => array(self::HAS_ONE, 'Smi', 'anagrafica_id'),

                     

                );

        }


nel metodo search()

public function search()

	{

		$criteria=new CDbCriteria;

		

		$criteria->with = array('smi');

...

}



nella gridview:

oltre agli altri campi: smi.datainvito,

e in particolare se non vuoi avere errori se datainvito o la relazione non esiste




array(

    'name'=>'data_invito',

    'value'=>'(isset($data->smi))?$data->smi->datainvito:"Nessun Valore"',

),



e impostaci un public $data_invito nel model Anagrafica, ti servirà anche nel caso in cui tu volessi filtrare e ordinare il campo


(Giuliano Ingrosso) #11

grazie mille spero che un giorno potro’ ringraziarti dell’aiuto.

funziona tutto e bene


(Giuliano Ingrosso) #12

scusa ancora.

hai idea perchè non funzionano i filtri ?


		$criteria->compare('cognome',$this->cognome,true);	

o provato anche a scrivere


		$criteria->compare('t.cognome',$this->cognome,true);	

il risultato della query è:


	

SELECT `t`.`id_anagrafica` AS `t0_c0`, `t`.`cognome` AS `t0_c3`, `t`.`nome` AS `t0_c4`, `t`.`sesso` AS `t0_c5`, `t`.`datadinascita` AS `t0_c7`, `t`.`codicefiscale` AS `t0_c8`, `t`.`luogo_di_nascita` AS `t0_c9`, `t`.`unita_operativa` AS `t0_c10`, `t`.`indirizzo` AS `t0_c12`, `t`.`residenza` AS `t0_c13`, `t`.`telefono` AS `t0_c14`, `t`.`note` AS `t0_c21`,  `t`.`note_particolari` AS `t0_c23`, `t`.`mail` AS `t0_c26`, `t`.`idsmi` AS `t0_c27`,  `idsmi0`.`idsmi` AS `t1_c0`, `idsmi0`.`idanagrafica` AS `t1_c1`, `idsmi0`.`datainvito` AS `t1_c3` FROM `anagrafica` `t` LEFT OUTER JOIN `smi` `idsmi0` ON (`idsmi0`.`idanagrafica`=`t`.`id_anagrafica`) ORDER BY dataultimasmi DESC LIMIT 15



e da qui non si vede nessuna clausola where. E’ normale ?


(Giuliano Ingrosso) #13

cosi funziona.




$criteria->compare('cognome','ING',true);




se metto la variabile no




$criteria->compare('cognome',$this->cognome,true);




(St4nny) #14

controlla di avare nelle rules di Anagrafica




..

array('cognome', 'safe', 'on'=>'search')

..




(Giuliano Ingrosso) #15

risolto ;D

nel controller, dovevo “riempire” il model con l’array $_POST e non $_GET




		if(isset($_POST['Anagrafica']))

			$model->attributes=$_POST['Anagrafica'];



:) thanks !