Pagina 1 di 6 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 54
  1. #1

    Query annidate o Join per estrarre dato

    Salve a tutti, ho un piccolo problemino.

    Ho due tabelle così composte

    Ordini
    ID | totale | ecc

    Stato Ordini
    ID | stato | id_ordine

    Devo estrarre gli ordini che hanno stato = a 2

    NB: Mi serve che lo stato = 2 sia verificato in quel momento.

    Cioè devono uscire solo gli ordini che come ultimo stato hanno 2, e non mi interessano gli ordini che, sono passati dallo stato 2, ma ora sono allo stato 3.

    Spero di essere stato chiaro!

    grazie!

  2. #2
    Utente di HTML.it L'avatar di nicola75ss
    Registrato dal
    Nov 2004
    Messaggi
    12,922
    Mi sembra ti serva una cosa del genere

    codice:
    select so1.* from stato_ordini as so1
    inner join (
    select *
    from stato_ordini
    order by id desc) as so2
    on so1.id = so2.id 
    group by so1.id_ordine
    having so1.stato = 2
    Se il risultato è quello atteso non devi far altro che un ulteriore join tra l'altra tabella e la mia query.

  3. #3
    Mi serviva proprio un tuo intervento.

    Me la spieghi in italiano?

    Grazie mille!!

    Edit: L'ho provata, in ogni caso sembra funzionare, ma se me la spieghi è sempre meglio così me la ricorderò!

  4. #4
    Utente di HTML.it L'avatar di nicola75ss
    Registrato dal
    Nov 2004
    Messaggi
    12,922
    La query interna come puoi vedere si limita ad ordinare tutti i record in ordine decrescente. La query esterna è messa in relazione con quella interna e poichè il group by restituisce il primo record che viene trovato per ogni identificativo d'ordine ti verrà restituito per ciascun gruppo quello con l'id maggiore.
    Infine con la clausola having limiti i record solo a quelli che soddisfano il tuo criterio di uguaglianza pari a 2.

    Spero di essere stato chiaro. Buona notte.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da nicola75ss
    Mi sembra ti serva una cosa del genere

    codice:
    select so1.* from stato_ordini as so1
    inner join (
    select *
    from stato_ordini
    order by id desc) as so2
    on so1.id = so2.id 
    group by so1.id_ordine
    having so1.stato = 2
    Se il risultato è quello atteso non devi far altro che un ulteriore join tra l'altra tabella e la mia query.
    giusto per spaccare il capello in 4 nella seconda select basta "select id" (che è il campo del join) anzichè "select *" (fetcha l'intera riga)


    EDIT: una soluzione alternativa, se gli stati sono ordinati, è una query dipendente. Attenzione che mysql le esegue molto male, comunque
    questo dovrebbe funzionare e di logica piuttosto semplice

    select * from ordini where id in (
    select id_ordine from stato_ordini group by id_ordine having max(stato)=2)

  6. #6
    in tutte e due le soluzioni proposte viene effettuata una sub-query, il che rallenta comunque (anche se quella di nicola, facendo una join, dovrebbe essere più performante).

    se puoi (dipende dalla versione di mysql) e se sei abituato (io oramai campo con quelle), prepara una sp che a) estrae gli id che ti interessano in una temp, b) mette le temp in join con la tabella principale come nella soluzione di nicola.


  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da optime
    in tutte e due le soluzioni proposte viene effettuata una sub-query, il che rallenta comunque (anche se quella di nicola, facendo una join, dovrebbe essere più performante).
    Togli il "forse", le query IN sono lentissime in mysql, soprattutto fino alla 5.5 (ma anche lì non è che siano eccezionali)


    Qualora si volesse fare qualcosa di "vagamente" performante la scelta migliore è la query interna che ho messo, salvataggio degli ID in forma temporanea, e poi la query esterna direttamente mettendo la serie degli ID separati da una , [la "in" con una serie di costanti è efficiente].

    Essendoci un max() l'ottimizzatore può usare bene un indice btree, con ottimi risultati se fai un indice combinato id_ordine;stato, diventa un range.

    Ovviamente se l'indice non c'è scatta un filesort + temporaneo, se l'indice è stato;id_ordine c'è sempre il risultato temporaneo di mezzo

  8. #8
    Grazie a tutti per l'ottimo contributo.

    Volevo chiedervi una cosa: a livello di prestazioni, impiega più tempo un INSERT o un UPDATE?!?

    Ovviamente con lo stesso numero di campi!

    Grazie ancora!

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da Samleo
    Grazie a tutti per l'ottimo contributo.

    Volevo chiedervi una cosa: a livello di prestazioni, impiega più tempo un INSERT o un UPDATE?!?

    Ovviamente con lo stesso numero di campi!

    Grazie ancora!
    non si può dire, in generale (ma in stra-generale) l'update, giacchè normalmente (anzi praticamente sempre) ha una condizione "where", che richiede la generazione di una lista di foglie sulle quali operare.

    l'insert invece richiede solo l'attraversamento dell'albero della chiave primaria per trovare la pagina giusta. qui però può esserci il problema del bilanciamento dell'albero degli indici, con relativo splitting etc.etc.

    In definitiva: dipende

  10. #10
    Originariamente inviato da Samleo
    Volevo chiedervi una cosa: a livello di prestazioni, impiega più tempo un INSERT o un UPDATE?!?
    ma che domanda è?

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.