+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16

Discussione: Query per estrapolare percentuale

  1. #1
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131

    Query per estrapolare percentuale

    Salve al tutto il gruppo, premetto che sono un neofita di MySql, ho iniziato da pochi giorni, me la cavo meglio in access, ora il problema si pone nell'esecuzione di una query che cerco di far girare,

    La query al completo è questa:
    codice:
    SELECT TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione, COUNT(TblRichieste.IdRichiesta) 
    AS Ricevute,(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione)
    AS Espletate, IF(Ricevute = 0 AND Espletate=0,0,ROUND(Espletate/Ricevute*100,2)) AS Percentuale
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione;
    ma appena la eseguo, mi viene restituito il seguente messaggio di errore:

    codice:
    1 queries executed, 0 success, 1 errors, 0 warnings
    
    Query: SELECT TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione, COUNT(TblRichieste.IdRichiesta) AS Ricevute,(SELECT COUNT(TblRich...
    
    Error Code: 1054
    Unknown column 'Ricevute' in 'field list'
    
    Execution Time : 0 sec
    Transfer Time  : 0 sec
    Total Time     : 0 sec

    in pratica non viene riconosciuto il campo Ricevute.

    Ma non appena tolgo la parte con l'IF :

    codice:
    IF(Ricevute = 0 AND Espletate=0,0,ROUND(Espletate/Ricevute*100,2)) AS Percentuale
    La query funziona benissimo.

    Come dovrei modificare la condizione che deve restituirmi anche lo 0 % ?

    Nell'Editor SQL di Access la query funziona perfettamente, ovviamente con l' IIF al posto dell'IF di MySql.

    Potete aiutarmi per favore?

    Come GUI per MySql uso L' SQLyog
    il Db è MySql 8.0
    Grazie
    Ultima modifica di Diego1966; 31-07-2019 01:42 

  2. #2
    L'avatar di AntonioG
    AntonioG non è in linea Moderatore Globale Ultimo blog: Commodore 64 e Codemotion
    Luogo
    Roma
    Post
    16,320
    Blogs
    5
    IF o IIF ?
    Avvisi generali e importanti, a pena CHIUSURA thread e/o BAN
    Il crossposting è vietato.
    Le richieste di "pappa pronta" sono vietate.
    Utilizzate i tag CODE per il codice.
    Leggere il Regolamento per chiarimenti PRIMA di creare nuovi thread.
    Utilizzare sempre i PM per comunicare con i moderatori.
    Non mi contattate in PM per problemi di software, usate il forum

  3. #3
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da AntonioG Visualizza il messaggio
    IF o IIF ?
    su Mysql IF, non accetta l'IIF

  4. #4
    Ferrari_and non è in linea Scolaretto
    Post
    116
    Ciao prova a sostituire nel If il campo Ricevute con il relativo count
    codice:
    IF((COUNT(TblRichieste.IdRichiesta) = 0 AND Espletate=0),0,ROUND(Espletate/Ricevute*100,2)) AS Percentuale
    Per qualche arcano motivo non riconosce gli as su campi aggregati come COUNT SUM MAX ecc....

  5. #5
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    311
    Quote Originariamente inviato da Ferrari_and Visualizza il messaggio
    Ciao prova a sostituire nel If il campo Ricevute con il relativo count...
    Non può funzionare... Il count semplice è diverso da quello che ottiene lui con l'alias [Ricevute].

    Quote Originariamente inviato da Ferrari_and Visualizza il messaggio
    Per qualche arcano motivo non riconosce gli as su campi aggregati come COUNT SUM MAX ecc....
    Il motivo è che gli alias, in quel momento dell'elaborazione, potrebbero non essere valutati. È tutto spiegato qui.

    La soluzione che adotterei io è quella di sfruttare una tabella temporanea, definita dalla subquery. Poi manderei in Join questa tabella temporanea e a questo punto i dati saranno disponibili perché elaborati prima della query principale.

  6. #6
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Non può funzionare... Il count semplice è diverso da quello che ottiene lui con l'alias [Ricevute].


    Il motivo è che gli alias, in quel momento dell'elaborazione, potrebbero non essere valutati. È tutto spiegato qui.

    La soluzione che adotterei io è quella di sfruttare una tabella temporanea, definita dalla subquery. Poi manderei in Join questa tabella temporanea e a questo punto i dati saranno disponibili perché elaborati prima della query principale.
    E come si fa?

    Qualcosa del genere?

    codice:
    SELECT TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione, COUNT(TblRichieste.IdRichiesta) AS 'Ricevute',(SELECT COUNT(TblRichieste.IdRichiesta) 
    
    FROM
    
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione) 
    AS 'Espletate'
    
    (CREATE TEMPORARY TABLE NewTbl SELECT COUNT(TblRichieste.IdRichiesta) 
    AS 'Ricevute',(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND 
    TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione) 
    AS 'Espletate' IF(Ricevute = 0 AND Espletate=0,0,ROUND(Espletate/Ricevute*100,2)) AS Percentuale 
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    LIMIT 0)
    
    
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione;
    Boh
    Ultima modifica di Diego1966; 31-07-2019 13:12 

  7. #7
    Ferrari_and non è in linea Scolaretto
    Post
    116
    Grazie per il link con la spiegazione.

    scusa ma perchè è diverso?
    Ultima modifica di Ferrari_and; 31-07-2019 16:25 

  8. #8
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Non può funzionare... Il count semplice è diverso da quello che ottiene lui con l'alias [Ricevute].


    Il motivo è che gli alias, in quel momento dell'elaborazione, potrebbero non essere valutati. È tutto spiegato qui.

    La soluzione che adotterei io è quella di sfruttare una tabella temporanea, definita dalla subquery. Poi manderei in Join questa tabella temporanea e a questo punto i dati saranno disponibili perché elaborati prima della query principale.
    Non c'è stato bisogno di una tabella temporanea, è bastata un'ulteriore subquery e funziona perfettamente.

    Posto il codice.

    codice:
    SELECT TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione, COUNT(TblRichieste.IdRichiesta) AS 'Ricevute',(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione) AS 'Espletate',
    
    ROUND((SELECT((SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione)*100/(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione))),2 )AS Percentuale
    
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione;
    Grazie comunque

    Anzi per completezza, giusto per non visualizzare il null nella colonna percentuale quando trova il valore di richiesta 0 ho messo un IF e il valore da null passa a zero:

    codice:
    SELECT TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione, COUNT(TblRichieste.IdRichiesta) AS 'Ricevute',(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione) AS 'Espletate',
    
    ROUND((SELECT IF((SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione)=0,0,(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblRichieste.Completata = TRUE AND TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione)*100/(SELECT COUNT(TblRichieste.IdRichiesta) FROM
    TblRichieste WHERE TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione))),2 )AS Percentuale
    
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione;
    Ultima modifica di Diego1966; 31-07-2019 19:02 

  9. #9
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    311
    Quote Originariamente inviato da Ferrari_and Visualizza il messaggio
    scusa ma perchè è diverso?
    Perdona la pochezza di informazioni. Ho risposto di getto, avendo a mente la precedente discussione, in cui abbiamo impostato la query.
    In effetti, per la parte che hai suggerito tu correttamente, è uguale. Io ero col pensiero all'alias [Espletate] che, come puoi notare, ha delle condizioni nella clausola WHERE. Ho fatto confusione.

    Quote Originariamente inviato da Diego1966 Visualizza il messaggio
    Non c'è stato bisogno di una tabella temporanea, è bastata un'ulteriore subquery e funziona perfettamente.
    Sono contento che tu sia riuscito a risolvere, ma ho solo un paio di dubbi che ti espongo:
    1) così facendo obblighi il motore di DB ad effettuare due volte le stesse ricerche. Fintanto che non sono impegnative, la differenza non la noti, ma quando cominci ad avere parecchi record secondo me inizia a pesare. Considera inoltre l'eventualità di modificare i parametri di ricerca dei record. Dovrai farlo in due parti distinte della query, con la possibile esposizione ad errori di copia/incolla o riscrittura, vista anche la (mia opinione personale) scarsa leggibilità delle istruzioni.
    2) hai rimosso l'IF, il che ti espone nuovamente alla divisione per zero ed ai relativi errori. Ora per reinserirlo dovresti effettuare una terza volta il Count sulle Ricevute (la condizione Espletate = 0 come già ti suggerivo nell'altra discussione è inutile quindi almeno quella te la potresti risparmiare).

    Quando mi ritrovo a dover gestire situazioni come la tua, io preferisco appoggiarmi a queste tabelle temporanee, così da avere anche un punto intermedio per verificare i record restituiti e facilitarmi la vita con il "debug".

    Imposterei la cosa così:
    codice:
    CREATE TEMPORARY TABLE Espletate
    (
      SELECT TblRichieste.IdCircoscrizione, COUNT(TblRichieste.IdRichiesta) As Espletate
      FROM TblRichieste
      WHERE TblRichieste.Completata = TRUE
      GROUP BY TblRichieste.IdCircoscrizione
    )
    SELECT
      TblCircoscrizioni.ID,
      TblCircoscrizioni.Circoscrizione,
      COUNT(TblRichieste.IdRichiesta) AS Ricevute,
      E.Espletate,
      IF(COUNT(TblRichieste.IdRichiesta)=0,0,ROUND(E.Espletate/COUNT(TblRichieste.IdRichiesta)*100,2)) AS Percentuale
    FROM TblCircoscrizioni
      LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
      LEFT JOIN Espletate as E On E.IdCircoscrizione = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione
    Ore, se volessi di nuovo reinserire il controllo delle date, sarà sufficiente farlo nella tabella temporanea perché le modifiche si vedano in entrambe le colonne. Se poi quel che estrapoli dalla tabella temporanea, ti può tornare utile in altre query, ti suggerisco di valutare l'utilizzo di una vista.

    P.S. Come già accennavo, non ho la possibilità di fare dei test, ma l'impostazione delle query dovrebbe essere corretta.

  10. #10
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Perdona la pochezza di informazioni. Ho risposto di getto, avendo a mente la precedente discussione, in cui abbiamo impostato la query.
    In effetti, per la parte che hai suggerito tu correttamente, è uguale. Io ero col pensiero all'alias [Espletate] che, come puoi notare, ha delle condizioni nella clausola WHERE. Ho fatto confusione.


    Sono contento che tu sia riuscito a risolvere, ma ho solo un paio di dubbi che ti espongo:
    1) così facendo obblighi il motore di DB ad effettuare due volte le stesse ricerche. Fintanto che non sono impegnative, la differenza non la noti, ma quando cominci ad avere parecchi record secondo me inizia a pesare. Considera inoltre l'eventualità di modificare i parametri di ricerca dei record. Dovrai farlo in due parti distinte della query, con la possibile esposizione ad errori di copia/incolla o riscrittura, vista anche la (mia opinione personale) scarsa leggibilità delle istruzioni.
    2) hai rimosso l'IF, il che ti espone nuovamente alla divisione per zero ed ai relativi errori. Ora per reinserirlo dovresti effettuare una terza volta il Count sulle Ricevute (la condizione Espletate = 0 come già ti suggerivo nell'altra discussione è inutile quindi almeno quella te la potresti risparmiare).

    Quando mi ritrovo a dover gestire situazioni come la tua, io preferisco appoggiarmi a queste tabelle temporanee, così da avere anche un punto intermedio per verificare i record restituiti e facilitarmi la vita con il "debug".

    Imposterei la cosa così:
    codice:
    CREATE TEMPORARY TABLE Espletate
    (
      SELECT TblRichieste.IdCircoscrizione, COUNT(TblRichieste.IdRichiesta) As Espletate
      FROM TblRichieste
      WHERE TblRichieste.Completata = TRUE
      GROUP BY TblRichieste.IdCircoscrizione
    )
    SELECT
      TblCircoscrizioni.ID,
      TblCircoscrizioni.Circoscrizione,
      COUNT(TblRichieste.IdRichiesta) AS Ricevute,
      E.Espletate,
      IF(COUNT(TblRichieste.IdRichiesta)=0,0,ROUND(E.Espletate/COUNT(TblRichieste.IdRichiesta)*100,2)) AS Percentuale
    FROM TblCircoscrizioni
      LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
      LEFT JOIN Espletate as E On E.IdCircoscrizione = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID, TblCircoscrizioni.Circoscrizione
    Ore, se volessi di nuovo reinserire il controllo delle date, sarà sufficiente farlo nella tabella temporanea perché le modifiche si vedano in entrambe le colonne. Se poi quel che estrapoli dalla tabella temporanea, ti può tornare utile in altre query, ti suggerisco di valutare l'utilizzo di una vista.

    P.S. Come già accennavo, non ho la possibilità di fare dei test, ma l'impostazione delle query dovrebbe essere corretta.

    Ciò che dici ha un senso, però capiscimi mi sono appena avicinato da un paio di giorni, devo ancora capire del tutto le dinamiche, che come ben saprai sono molto diverse da access, l'IF non lo rimosso, l'ho inserito invece : ROUND((SELECT
    codice:
    IF((SELECT COUNT(TblRichieste.IdRichiesta) FROM
    Per quanto riguarda il verificare il tuo script, lo faccio subito e ti dico .

+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi