Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it L'avatar di carlo2002
    Registrato dal
    Jun 2002
    Messaggi
    2,746

    [MySQL] Aiuto per una query

    Ho le seguenti tabelle:


    Tabella 'utenti'
    - id_utente
    - nome


    Tabella 'cose_da_condividere'
    - id_cosa_da_condividere


    Tabella 'condivisioni'
    - id_condivisione
    - id_cosa_da_condividere
    - id_utente_condivisore


    Devo estrarre l'elenco degli utenti che ancora non sono associati ad una determinata condivisione

    sto provando così ma non esce alcun risultato

    Codice PHP:
    $query "

    SELECT id_utente,nome 

    FROM utenti

    LEFT JOIN condivisioni

    ON   utenti.id_utente = condivisioni.id_utente_condivisore

    WHERE id_cosa_da_condividere = '"
    .$_REQUEST['id_cosa_da_condividere']."'

    AND   id_utente <> '"
    .$_dati_utente['id_utente']."'  # escludo l'utente che fa la condivisione

    AND   condivisioni.id_utente_condivisore IS NULL

    ORDER BY nome ASC " 

    dove sbaglio ???

    grazie
    Errare humanum est, perseverare ovest

  2. #2
    Utente di HTML.it L'avatar di Joe Taras
    Registrato dal
    Nov 2003
    residenza
    Taranto
    Messaggi
    955

    Re: [MySQL] Aiuto per una query

    Originariamente inviato da carlo2002
    Ho le seguenti tabelle:


    Tabella 'utenti'
    - id_utente
    - nome


    Tabella 'cose_da_condividere'
    - id_cosa_da_condividere


    Tabella 'condivisioni'
    - id_condivisione
    - id_cosa_da_condividere
    - id_utente_condivisore


    Devo estrarre l'elenco degli utenti che ancora non sono associati ad una determinata condivisione

    sto provando così ma non esce alcun risultato

    Codice PHP:
    $query "

    SELECT id_utente,nome 

    FROM utenti

    LEFT JOIN condivisioni

    ON   utenti.id_utente = condivisioni.id_utente_condivisore

    WHERE id_cosa_da_condividere = '"
    .$_REQUEST['id_cosa_da_condividere']."'

    AND   id_utente <> '"
    .$_dati_utente['id_utente']."'  # escludo l'utente che fa la condivisione

    AND   condivisioni.id_utente_condivisore IS NULL

    ORDER BY nome ASC " 

    dove sbaglio ???

    grazie
    codice:
    SELECT * FROM utenti u
    WHERE NOT EXISTS(SELECT 'x' FROM condivisione co WHERE co.id_utente_condivisore = u.id
    and co.id_cosa_da_condividere = VARIABILE_TUA)

  3. #3
    Utente di HTML.it L'avatar di carlo2002
    Registrato dal
    Jun 2002
    Messaggi
    2,746
    Grazie molto gentile.

    Però mi interessava di più risolvere tramite una classica Left Outer Join, anche perchè è la prima volta che la uso e mi sembra adatta a questo scopo.

    Se poi mi confermate che per il mio scopo con una Left Outer Join non si risolve allora adotterò volentieri il tuo codice.
    Errare humanum est, perseverare ovest

  4. #4
    Utente di HTML.it L'avatar di carlo2002
    Registrato dal
    Jun 2002
    Messaggi
    2,746
    Codice PHP:
    $query "

    SELECT id_utente,nome 

    FROM utenti

    LEFT JOIN condivisioni

    ON   utenti.id_utente = condivisioni.id_utente_condivisore

    WHERE condivisioni.id_utente_condivisore IS NULL

    AND   id_utente <> '"
    .$_dati_utente['id_utente']."'  # escludo l'utente che fa la condivisione

    ORDER BY nome ASC " 

    Ecco così funziona ma ho dovuto togliere la condizione

    codice:
    AND id_cosa_da_condividere = '".$_REQUEST['id_cosa_da_condividere']."'
    Che però mi serve ma se la inserisco non ottengo più alcun risultato

    ...ma cos'è, forse le Outer Join si devono fare solo su tabelle prese interamente?
    Errare humanum est, perseverare ovest

  5. #5
    Utente di HTML.it L'avatar di Joe Taras
    Registrato dal
    Nov 2003
    residenza
    Taranto
    Messaggi
    955
    Originariamente inviato da carlo2002
    Codice PHP:
    $query "

    SELECT id_utente,nome 

    FROM utenti

    LEFT JOIN condivisioni

    ON   utenti.id_utente = condivisioni.id_utente_condivisore

    WHERE condivisioni.id_utente_condivisore IS NULL

    AND   id_utente <> '"
    .$_dati_utente['id_utente']."'  # escludo l'utente che fa la condivisione

    ORDER BY nome ASC " 

    Ecco così funziona ma ho dovuto togliere la condizione

    codice:
    AND id_cosa_da_condividere = '".$_REQUEST['id_cosa_da_condividere']."'
    Che però mi serve ma se la inserisco non ottengo più alcun risultato

    ...ma cos'è, forse le Outer Join si devono fare solo su tabelle prese interamente?
    Devi usare la not exists...

  6. #6
    Utente di HTML.it L'avatar di carlo2002
    Registrato dal
    Jun 2002
    Messaggi
    2,746
    Originariamente inviato da Joe Taras
    Devi usare la not exists...
    Ok, ma vorrei capire. Cercando in Internet vedo che l'Outer Join serve ad estrarre i record di una tabella che non hanno corrispondenza nell'altra.

    Nel manuale di riferimento di MySQL l'esempio viene fatto proprio con IS Null
    codice:
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    In un articolo di questo stesso sito l'esempio viene riportato con IS NULL ed addirittura con una condizione in più
    codice:
    SELECT * FROM ordini as o LEFT JOIN clienti as c ON o.idCliente = c.idCliente
    WHERE idOrdine > 1000 AND c.idCliente IS NULL
    Io ti ringrazio che mi hai dato direttamente del codice e sicuramente mi insegna qualcosa e mi tornerà utile, però adesso desidererei capire proprio perchè la Left Outer Join che ho confezionato non funziona.

    Eppure ho semplicemente usato esempi che ho trovato in Internet.

    La pappa pronta l'ho ricevuta ma una spiegazione sarebbe utile visto che informazioni in merito, pur cercando, non ne sto trovando, magari potrebbe tornare utile anche ad altri. Imho
    Errare humanum est, perseverare ovest

  7. #7
    Utente di HTML.it L'avatar di Joe Taras
    Registrato dal
    Nov 2003
    residenza
    Taranto
    Messaggi
    955
    Originariamente inviato da carlo2002
    Ok, ma vorrei capire. Cercando in Internet vedo che l'Outer Join serve ad estrarre i record di una tabella che non hanno corrispondenza nell'altra.

    Nel manuale di riferimento di MySQL l'esempio viene fatto proprio con IS Null
    codice:
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    In un articolo di questo stesso sito l'esempio viene riportato con IS NULL ed addirittura con una condizione in più
    codice:
    SELECT * FROM ordini as o LEFT JOIN clienti as c ON o.idCliente = c.idCliente
    WHERE idOrdine > 1000 AND c.idCliente IS NULL
    Io ti ringrazio che mi hai dato direttamente del codice e sicuramente mi insegna qualcosa e mi tornerà utile, però adesso desidererei capire proprio perchè la Left Outer Join che ho confezionato non funziona.

    Eppure ho semplicemente usato esempi che ho trovato in Internet.

    La pappa pronta l'ho ricevuta ma una spiegazione sarebbe utile visto che informazioni in merito, pur cercando, non ne sto trovando, magari potrebbe tornare utile anche ad altri. Imho
    Ciao,
    la exists può essere il più delle volte più veloce di una LEFT OUTER JOIN e già questo può essere un buon motivo per usare la seconda invece della prima

    In ogni caso
    codice:
    $query = " 
    
    SELECT id_utente,nome  
    
    FROM utenti 
    
    LEFT JOIN condivisioni 
    
    ON   utenti.id_utente = condivisioni.id_utente_condivisore 
    
    WHERE id_cosa_da_condividere = '".$_REQUEST['id_cosa_da_condividere']."' 
    
    AND   id_utente <> '".$_dati_utente['id_utente']."'  # escludo l'utente che fa la condivisione 
    
    AND   condivisioni.id_utente_condivisore IS NULL 
    
    ORDER BY nome ASC " ;
    La tua query credo non funzioni a dovere perché stai inserendo nella WHERE condizioni che invece dovrebbero essere presenti nella clausola ON.
    Infatti se nella INNER JOIN ciò che metti nella WHERE e ciò che metti nella ON non fa differenza, nella LEFT / RIGHT JOIN la fa e come!

    Perché ciò che metti nella ON rientra nelle logiche di "fusione" delle due tabelle, ciò che metti nella WHERE viene applicato come filtro dopo la fusione.

    Andando nello specifico, mettere nella WHERE questa parte:
    codice:
    id_cosa_da_condividere = '".$_REQUEST['id_cosa_da_condividere']."'
    è errato perché se tu vuoi estrarre tutti gli utente che NON hanno quella cosa da condividere, vuol dire che quel campo sarà NULL invece tu gli poni una condizione che deve essere uguale a qualcosa, di conseguenza non ti uscirà nulla, quindi quella condizione va nella clausola ON.

    Per il resto dovrebbe andare tutto bene ma ti consiglio di mettere sempre, quando fai delle JOIN la tabella davanti al campo, anche se non hai problemi di ambuigità perché ti aiutano a leggere meglio il codice.

    Spero di essere stato chiaro, buona serata

  8. #8
    Utente di HTML.it L'avatar di carlo2002
    Registrato dal
    Jun 2002
    Messaggi
    2,746
    Intanto sto usando NOT EXISTS e sta funzionando bene
    Codice PHP:
    $query "
    SELECT id_utente,nome 

    FROM utenti AS u

    WHERE NOT EXISTS (

    SELECT 'x' 

    FROM  condivisioni AS co

    WHERE co.id_utente_condivisore = u.id_utente

    AND   co.id_cosa_da_condividere = '"
    .$_REQUEST['id_cosa_da_condividere']."'

    )

    AND   u.id_utente <> '"
    .$_dati_utente['id_utente']."'   # escludo l'utente che fa la condivisione

    ORDER BY u.nome ASC

    Poi ti ringrazio molto per i consigli e per la spiegazione più approfondita che hai elargito. So che ciò richiede maggior tempo ma in un forum come questo lo trovo utile ed educativo e mi ha dato il giusto input per indirizzare meglio la mia comprensione.

    Ho provato ad aggiungere la condizione di ricerca nella clausola ON in SQL standard
    codice:
    ON   utenti.id_utente = condivisioni.id_utente_condivisore 
    
    AND   id_cosa_da_condividere = '".$_REQUEST['id_cosa_da_condividere']."'
    ma purtroppo non funziona

    Su un libro ho trovato che diverse implementazioni di SQL non accettano questa sintassi e quindi sconsigliano di mettere nella clausola ON criteri che non mettono in comparazione colonne da entrambe le tabelle.

    Per risolvere il problema consigliano di usare una simile condizione di ricerca nella clausola WHERE in una SELECT incorporata.

    Sto tentando di fare questo ma sono in alto mare, ora non so se chiedo troppo ma se tu o a qualsiasi altro che legge potesse fare un esempio senza il NOT EXISTS mantenendo la forma dell' OUTER JOIN sarebbe utile.

    Grazie comunque
    Errare humanum est, perseverare ovest

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.