Acquista i nostri libri consigliati su Amazon.it
+ Rispondi al messaggio
Visualizzazione dei risultati da 1 a 10 su 10

Costruzione query con INNER JOIN e OUTER JOIN in Access

  1. #1
    Zio_Panzu non è in linea Scolaretto
    Salve a tutti!!!
    So che questa è una delle basi di Access, ma mi trovo davvero in difficoltà per una cosa che dovrebbe essere semplicissima.

    In pratica, ho una query abbastanza articolata che tocca diverse tabelle. Alcune di queste dovrebbero essere collegate tramite INNER JOIN, altre tramite OUTER JOIN.

    In Oracle, avrei scritto la seguente query, utilizzando l'operatore "(+)" per indicare l'OUTER JOIN.

    SELECT	InterventoEstintore.CONTROLLO, InterventoEstintore.REVISIONE, InterventoEstintore.COLLAUDO, InterventoEstintore.FORNITURA, InterventoEstintore.NOLEGGIO, 			InterventoEstintore.NOTE,
    		ModelloEstintore.TIPO_ESTINGUENTE, ModelloEstintore.CAPIENZA, ModelloEstintore.MARCA, ModelloEstintore.CLASSE_FUOCO,
    			ModelloEstintore.APPROVAZIONE_MINISTERIALE,
    		Estintore.MATRICOLA, Estintore.ANNO_COSTRUZIONE, Estintore.LOTTO, Estintore.CE, Estintore.UBICAZIONE_NOTE, Estintore.SCADENZA_COLLAUDO,
    		Intervento.DATA_INTERVENTO, Intervento.NUM_INTERVENTO, Intervento.DESTINAZIONE,
    		TAnagrafica.Indirizzo & " - " & TAnagrafica.Cap & " " & TAnagrafica.Citta & " (" & TAnagrafica.Prov & ")" AS TAnagrafica.Indirizzo, TAnagrafica.	
    			CodAnagr, TAnagrafica.Nome, TAnagrafica.Referente,
    		TAnagraficaDest.Indirizzo & " - " & TAnagraficaDest.Cap & " " & TAnagraficaDest.Citta & " (" & TAnagraficaDest.Prov & ")" AS TAnagraficaDest.Indirizzo, 	TAnagraficaDest.CodDest, TAnagraficaDest.Referente,
    		Automezzo.TARGA_AUTOMEZZO, TAnagraficaDest.TARGA_RIMORCHIO, TAnagraficaDest.REFERENTE, TAnagraficaDest.CONTATTO
    FROM Intervento, Estintore, ModelloEstintore, InterventoEstintore, TAnagraficaDest, TAnagrafica, Automezzo
    WHERE 	InterventoEstintore.ID_INTERVENTO = Intervento.ID_INTERVENTO
    AND 	        InterventoEstintore.ID_ESTINTORE = Estintore.ID_ESTINTORE	
    AND		Estintore.ID_MODELLO = ModelloEstintore.ID_MODELLO
    AND		Intervento.ID_CLIENTE = TAnagrafica.IDAnagr
    AND		Estintore.ID_CLIENTE = TAnagrafica.IDAnagr
    AND		Estintore.COD_SEDE (+) = TAnagraficaDest.CodDest
    AND		Estintore.ID_AUTOMEZZO (+) = Automezzo.ID_AUTOMEZZO
    AND		TAnagrafica.IDAnagr = TAnagraficaDest.IDAnagr (+)
    AND		Intervento.COD_SEDE (+) = TAnagraficaDest.CodDest
    AND		TAnagrafica.IDAnagr = Automezzo.IDAnagr (+) 
    AND		Intervento.ID_AUTOMEZZO (+) = Automezzo.ID_AUTOMEZZO
    AND           Estintore.DISMESSO <> True;
    
    In Access, però, non ho trovato nulla di simile ed il tutto viene gestito con il SQL classico che, ahimè, ho scoperto di non riuscire a padroneggiare bene, per quanto riguarda i JOIN diversi dagli INNER.

    Partendo da questo schema
    SELECT campi
    FROM tabella1 INNER JOIN
    (tabella2 INNER JOIN ( tabella3
    INNER JOIN ( tabellax INNER JOIN ...)
    ON tabella3.campo3 operatorediconfronto tabellax.campox)
    ON tabella2.campo2 operatorediconfronto tabella3.campo3)
    ON tabella1.campo1 operatorediconfronto tabella2.campo2;
    
    , come faccio ad arrivare alla mia query?

  2. #2
    Zio_Panzu non è in linea Scolaretto
    Ciao a tutti!
    Ho cercato di sistemare la query, seguendo l'esempio dello schema generico. Quel che mi è venuto fuori è stato questo:
    SELECT	 InterventoEstintore.CONTROLLO, InterventoEstintore.REVISIONE, InterventoEstintore.COLLAUDO, InterventoEstintore.FORNITURA, InterventoEstintore.NOLEGGIO, 			InterventoEstintore.NOTE,
    		ModelloEstintore.TIPO_ESTINGUENTE, ModelloEstintore.CAPIENZA, ModelloEstintore.MARCA, ModelloEstintore.CLASSE_FUOCO,
    			ModelloEstintore.APPROVAZIONE_MINISTERIALE,
    		Estintore.MATRICOLA, Estintore.ANNO_COSTRUZIONE, Estintore.LOTTO, Estintore.CE, Estintore.UBICAZIONE_NOTE, Estintore.SCADENZA_COLLAUDO,
    		Intervento.DATA_INTERVENTO, Intervento.NUM_INTERVENTO, Intervento.DESTINAZIONE,
    		TAnagrafica.Indirizzo & " - " & TAnagrafica.Cap & " " & TAnagrafica.Citta & " (" & TAnagrafica.Prov & ")" AS Indirizzo, TAnagrafica.	
    			CodAnagr, TAnagrafica.Nome, TAnagrafica.Referente,
    		TAnagraficaDest.Indirizzo & " - " & TAnagraficaDest.Cap & " " & TAnagraficaDest.Citta & " (" & TAnagraficaDest.Prov & ")" AS IndirizzoSede, 	TAnagraficaDest.CodDest, TAnagraficaDest.Referente,
    		Automezzo.TARGA_AUTOMEZZO, TAnagraficaDest.TARGA_RIMORCHIO, TAnagraficaDest.REFERENTE, TAnagraficaDest.CONTATTO
    FROM 
    	Intervento INNER JOIN (InterventoEstintore 
    		INNER JOIN (Estintore 
    			INNER JOIN (ModelloEstintore 
    				INNER JOIN (TAnagrafica 
    					RIGHT OUTER JOIN (TAnagraficaDest
    						RIGHT OUTER JOIN Automezzo ON (TAnagrafica.IDAnagr = Automezzo.IDAnagr AND Estintore.ID_AUTOMEZZO = Automezzo.ID_AUTOMEZZO AND Intervento.ID_AUTOMEZZO = Automezzo.ID_AUTOMEZZO))
    					ON (TAnagrafica.IDAnagr = TAnagraficaDest.IDAnagr AND TAnagraficaDest.CodDest = Intervento.COD_SEDE AND Estintore.COD_SEDE = TAnagraficaDest.CodDest))
    				ON (Intervento.ID_CLIENTE = TAnagrafica.IDAnagr AND Estintore.ID_CLIENTE = TAnagrafica.IDAnagr))
    			ON Estintore.ID_MODELLO = ModelloEstintore.ID_MODELLO)
    		ON InterventoEstintore.ID_ESTINTORE = Estintore.ID_ESTINTORE)
    	ON Intervento.ID_INTERVENTO = InterventoEstintore.ID_INTERVENTO
    WHERE Estintore.DISMESSO <> True;
    
    che, logicamente, mica poteva funzionare al primo colpo...
    Cosa sbaglio?

  3. #3
    Zio_Panzu non è in linea Scolaretto
    Ciao,
    chiedo cortesemente di chiudere questo thread in modo che possa porre questa domanda in un forum che tratti più in generale dei problemi su SQL (senza sconfinare nel Crosspost).
    Ho evidentemente postato la mia domanda (troppo generica) su un forum che ha argomenti ben precisi.
    Grazie comunque a tutti coloro che hanno prestato attenzione alla mia richiesta.

  4. #4
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    ℹ️ Leggi di più su @Alex ...

  5. #5
    Zio_Panzu non è in linea Scolaretto
    Alex, grazie per i link.
    Scomponendo la query e cercando di capire i meccanismi, mi son reso conto che effettivamente c'è qualcosa di serio che sbaglio nell'approcciarmi ai JOIN.
    Finora li ho sempre gestiti nella clausola WHERE, ora che li uso nella FROM, devo far bene attenzione a come costruisco il tutto.

    Semplificando e scomponendo la query iniziale, sono giunto a questa
    <CODE>
    SELECT *
    FROM Intervento
    INNER JOIN (InterventoEstintore
    INNER JOIN (Estintore
    INNER JOIN TAnagrafica
    ON Estintore.ID_CLIENTE = TAnagrafica.IDAnagr)
    ON InterventoEstintore.ID_ESTINTORE = Estintore.ID_ESTINTORE)
    ON Intervento.ID_INTERVENTO = InterventoEstintore.ID_INTERVENTO;
    </CODE>
    che funziona correttamente.
    Se però cambio
    <CODE>ON Estintore.ID_CLIENTE = TAnagrafica.IDAnagr</CODE>
    in
    <CODE>ON Intervento.ID_CLIENTE = TAnagrafica.IDAnagr</CODE>
    Giustamente non funziona più perchè mando a farsi benedire la INNER JOIN relativa.
    A questo punto, devo vedere come sistemare la query originale per portare nella clausola FROM i controlli che facevo nella clausola WHERE.
    Consigli?

  6. #6
    Zio_Panzu non è in linea Scolaretto
    Ho provato a seguire un po' di esempi in giro per la rete e per problemi SIMILI ci sono state soluzioni simili a questa

    SELECT *
    FROM Intervento
    INNER JOIN (InterventoEstintore
    INNER JOIN (Estintore
    INNER JOIN TAnagrafica
    ON ((Estintore.ID_CLIENTE = TAnagrafica.IDAnagr) AND (Intervento.ID_CLIENTE = TAnagrafica.IDAnagr))
    ON InterventoEstintore.ID_ESTINTORE = Estintore.ID_ESTINTORE)
    ON Intervento.ID_INTERVENTO = InterventoEstintore.ID_INTERVENTO;

    ...naturalmente a me non funziona... :S

  7. #7
    Zio_Panzu non è in linea Scolaretto
    So che ormai sembra che parli da solo, però aggiorno i miei risultati in modo che sia più semplice, per chi legge, capire i miei dubbi.

    Innanzitutto: EUREKA!!! (sono riuscito a creare una base di partenza, funzionante, che include tutte le tabelle con INNER ed OUTER JOIN e che lascia fuori solo alcuni vincoli).

    SELECT *
    FROM ((((((
    		Intervento INNER JOIN InterventoEstintore ON Intervento.ID_INTERVENTO = InterventoEstintore.ID_INTERVENTO)
    		INNER JOIN Estintore ON InterventoEstintore.ID_ESTINTORE = Estintore.ID_ESTINTORE)
    		INNER JOIN TAnagrafica ON Estintore.ID_CLIENTE = TAnagrafica.IDAnagr AND Intervento.ID_CLIENTE = TAnagrafica.IDAnagr)
    		INNER JOIN ModelloEstintore ON Estintore.ID_MODELLO = ModelloEstintore.ID_MODELLO)
    		LEFT OUTER JOIN TAnagraficaDest ON TAnagrafica.IDAnagr = TAnagraficaDest.IDAnagr)
    		LEFT OUTER JOIN Automezzo ON TAnagrafica.IDAnagr = Automezzo.ID_CLIENTE)
    
    Il mio problema nasce dal fatto che i due OUTER JOIN dovrebbero essere così
    LEFT OUTER JOIN TAnagraficaDest ON TAnagrafica.IDAnagr = TAnagraficaDest.IDAnagr AND Intervento.COD_SEDE = TAnagraficaDest.CodDest AND Estintore.COD_SEDE = TAnagraficaDest.CodDest)
    
    LEFT OUTER JOIN Automezzo ON TAnagrafica.IDAnagr = Automezzo.IDAnagr AND Estintore.ID_AUTOMEZZO = Automezzo.ID_AUTOMEZZO AND Intervento.ID_AUTOMEZZO = Automezzo.ID_AUTOMEZZO)
    
    Quando eseguo la query con il secondo pezzo di codice, viene visualizzato l'errore "Espressione JOIN non supportata".

  8. #8
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    Prova a spezzare la Query in 2 Queries... nella 2° prendi la 1° ed aggiungi il 2° OUTER conprendendo ovviamente tutti gli elementi necessari...

    Ovviamente è un tentativo per capire se è un problema di predicato complesso o altro...
    ℹ️ Leggi di più su @Alex ...

  9. #9
    Zio_Panzu non è in linea Scolaretto
    Quote Originariamente inviato da @Alex Visualizza il messaggio
    Prova a spezzare la Query in 2 Queries... nella 2° prendi la 1° ed aggiungi il 2° OUTER conprendendo ovviamente tutti gli elementi necessari...

    Ovviamente è un tentativo per capire se è un problema di predicato complesso o altro...
    Anche se inserisco un solo OUTER JOIN (completo), ricevo lo stesso errore.
    Andando a spulciare la documentazione relativa all'errore, pare dipenda da una sorta di ambiguità dell'outer join dovuta alla variazione dei risultati in base all'ordine dei vincoli all'interno del JOIN.

  10. #10
    Zio_Panzu non è in linea Scolaretto
    RISOLTO!!! (devo solo verificare la correttezza dei dati estratti. La logica mi sembra corretta come anche il numero di record estratti)
    In pratica ho splittato gli OUTER JOIN creando degli alias di tabelle nel seguente modo:

    SELECT *
    FROM ((((((((((
    Intervento INNER JOIN InterventoEstintore ON Intervento.ID_INTERVENTO = InterventoEstintore.ID_INTERVENTO)
    INNER JOIN Estintore ON InterventoEstintore.ID_ESTINTORE = Estintore.ID_ESTINTORE)
    INNER JOIN TAnagrafica ON Estintore.ID_CLIENTE = TAnagrafica.IDAnagr AND Intervento.ID_CLIENTE = TAnagrafica.IDAnagr)
    INNER JOIN ModelloEstintore ON Estintore.ID_MODELLO = ModelloEstintore.ID_MODELLO)
    LEFT OUTER JOIN TAnagraficaDest AS t1 ON t1.IDAnagr = TAnagrafica.IDAnagr)
    LEFT OUTER JOIN TAnagraficaDest AS t2 ON t2.CodDest = Intervento.COD_SEDE)
    LEFT OUTER JOIN TAnagraficaDest AS t3 ON t3.CodDest = Estintore.COD_SEDE)
    LEFT OUTER JOIN Automezzo AS a1 ON a1.ID_CLIENTE = TAnagrafica.IDAnagr)
    LEFT OUTER JOIN Automezzo AS a2 ON a2.ID_AUTOMEZZO = Estintore.ID_AUTOMEZZO)
    LEFT OUTER JOIN Automezzo AS a3 ON a3.ID_AUTOMEZZO = Intervento.ID_AUTOMEZZO)

    BRAVO ME!

+ Rispondi al messaggio

Potrebbero interessarti anche ...

  1. Costruzione inner join
    Da luca1963 nel forum PHP
    Risposte: 2
    Ultimo Post: 07-06-2018, 11:43
  2. ACCESS 2007 - Outer Join
    Da colte nel forum Microsoft Access
    Risposte: 4
    Ultimo Post: 13-10-2011, 19:24
  3. [vba][access] join query da vba problema
    Da antony85 nel forum Microsoft Access
    Risposte: 3
    Ultimo Post: 27-06-2008, 16:15
  4. full outer join
    Da nina nel forum Microsoft Word
    Risposte: 5
    Ultimo Post: 28-09-2007, 11:36
  5. [Teoria]Differenza tra Natural join ed equi-join
    Da newpc82 nel forum Altri Database Server
    Risposte: 2
    Ultimo Post: 29-06-2007, 01:11