Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1

    [mysql] problema logico Left join su 4 tabelle

    Salve a tutti,
    ho un problema logico (semplice, banale, sicuramente da niubbo) per trovare un id su N tabelle associative.
    Questo lo schema di esempio
    Codice PHP:
    ACCOUNT
    -------+-----+
    name uid |
    -------+-----+
    aaa  |   |
    bbb  |   |
    ccc  |   |
    ddd  |   |
    eee  |   |
    -------+-----+

    PIPPO
    -------+-----+
    piid uid |
    -------+-----+
    1    |   |
    2    |   |
    -------+-----+

    PLUTO
    -------+-----+
    plid uid |
    -------+-----+
    1    |   |
    -------+-----+

    PAPERINO
    -------+-----+
    paid uid |
    -------+-----+
    |      |     |
    -------+-----+ 

    In pratica ho i vari uid della tabella ACCOUNT presenti (o NON presenti) nelle altre tabelle PIPPO, PLUTO e PAPERINO
    Quello che voglio ottenere è l'elenco degli UID che sono presenti nelle tabelle PIPPO, PLUTO e PAPERINO ovvero:


    Codice PHP:
    -------+-----+
    1    |   |
    2    |   |
    -------+-----+ 

    Fare una cosa così ovviamente mi tira fuori tutti gli UID che sono presenti anche nella tabella ACCOUNT
    Codice PHP:
    SELECT FROM ACCOUNT
    LEFT JOIN PIPPO ON PIPPO
    .uid ACCOUNT.uid 
    LEFT JOIN PLUTO ON PLUTO
    .uid ACCOUNT.uid
    LEFT JOIN PAPERINO ON PAPERINO
    .uid ACCOUNT.uid 

    Fare così funziona ma non mi piace e volevo trovare qualcosa di più efficiente:
    Codice PHP:
    SELECT FROM ACCOUNT
    WHERE
    ACCOUNT
    .uid IN (SELECT uid FROM PIPPO) OR
    ACCOUNT.uid IN (SELECT uid FROM PLUTO) OR
    ACCOUNT.uid IN (SELECT uid FROM PAPERINO

    Dove sbaglio? :\
    Ultima modifica di PazZII; 05-01-2014 a 00:40

  2. #2
    perché dici che la prima query NON è efficiente?

  3. #3
    Quote Originariamente inviata da optime Visualizza il messaggio
    perché dici che la prima query NON è efficiente?
    questa?
    Codice PHP:
    SELECT FROM ACCOUNT
    WHERE
    ACCOUNT
    .uid IN (SELECT uid FROM PIPPO) OR
    ACCOUNT.uid IN (SELECT uid FROM PLUTO) OR
    ACCOUNT.uid IN (SELECT uid FROM PAPERINO
    Bò... vedo select select select select non so, non c'è forse un modo più veloce usando left join?
    Non so, chiedo.

  4. #4
    ho detto "la prima", quella con le join, perché mi chiedi della seconda? se il problema è che ti tira fuori tutti gli account, semplicemente non usare LEFT (che vuol dire appunto leggi TUTTO quello che è nella tabella a di sinistra anche se non corrisponde alla tabella di destra), ma INNER. E non si tratta di efficienza, ma di coerenza con la richiesta

  5. #5
    Quote Originariamente inviata da optime Visualizza il messaggio
    ho detto "la prima", quella con le join, perché mi chiedi della seconda? se il problema è che ti tira fuori tutti gli account, semplicemente non usare LEFT (che vuol dire appunto leggi TUTTO quello che è nella tabella a di sinistra anche se non corrisponde alla tabella di destra), ma INNER. E non si tratta di efficienza, ma di coerenza con la richiesta
    Giusto hai ragione.
    Sai però che mi pare con inner join non mi funzionava?
    Faccio una prova ulteriore.

  6. #6
    Esatto non mi funziona.
    So che sarà una stupidaggine ma non capisco (letto ovunque e concettualmente non mi pare di commettere errori)
    Codice PHP:
    SELECT FROM ACCOUNT
    INNER JOIN PIPPO ON PIPPO
    .uid ACCOUNT.uid 
    INNER JOIN PLUTO ON PLUTO
    .uid ACCOUNT.uid
    INNER JOIN PAPERINO ON PAPERINO
    .uid ACCOUNT.uid 
    Questa mi dà zero risultati, dove sbaglio? :\

  7. #7
    prova con

    SELECT * FROM ACCOUNT
    INNER JOIN
    ( SELECT UID FROM PIPPO
    UNION ALL
    SELECT UID FROM
    PLUTO
    UNION ALL
    SELECT UID FROM
    PAPERINO ) T1
    ON
    ACCOUNT.uid = T1.uid

  8. #8
    Sì funziona.
    Capito
    Grazie!!!

  9. #9
    Fare così funziona ma non mi piace e volevo trovare qualcosa di più efficiente:
    Codice PHP:
    SELECT FROM ACCOUNT
    WHERE
    ACCOUNT
    .uid IN (SELECT uid FROM PIPPO) OR
    ACCOUNT.uid IN (SELECT uid FROM PLUTO) OR
    ACCOUNT.uid IN (SELECT uid FROM PAPERINO


    Una soluzione alternativa molto più efficiente della IN è usare la EXISTS come segue:
    SELECT *
    FROM ACCOUNT
    WHERE
    EXISTS (SELECT 1 FROM FROM PIPPO WHERE PIPPO.uid=ACCOUNT.uid) OR
    EXISTS (SELECT 1 FROM FROM PLUTO WHERE PLUTO.uid=ACCOUNT.uid) OR
    EXISTS (SELECT 1 FROM FROM PAPERINO WHERE PAPERINO.uid=ACCOUNT.uid)

    La differenza è che la EXISTS si "ferma" appena ha trovato il primo dei valori che soddisfano la condizione posta.
    Se ti stai approcciando all'argomento database dai uno sguardo anche a: SQL, database relazionale, regole di Codd, modello E-R, forme normali, normalizzazione con il mio testo: Semplicemente Database

  10. #10
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    ...sicuro sicuro?
    Così diventa una subquery correlata e viene rieseguita per ogni riga di account....

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.