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

Discussione: Count e subquery per restituire due valori di cui uno con parametro e percentuale

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

    Count e subquery per restituire due valori di cui uno con parametro e percentuale

    Buongiorno al gruppo, come da titolo:

    Avendo una Tabella, TblRichieste relazionata 1 a Molti con la tabella circoscrizione (TblCircoscrizione 1, TblRichieste Molti), dove i campi da tenere in considerazione sono nella Tabella TblRichieste: IdCircoscrizione FK, e IdRichieste PK, ho necessità di estrapolare due valori che abbiano come riferimento l'IdCircoscrizione; il primo valore lo restituisce il Count del campo IdRichiesta che è l'Alias "Ricevute" senza paramentri, quindi tutte le richieste sia Ricevute che Espletate, La tabella ha un Campo Booleano "Completata" SI-NO, che in questa SELECT non viene usato, il secondo valore viene restituito da un secondo Count sempre sul campo IdRichiesta, che è l'Alias "Espletate", ma stavolta dove il campo Booleano "Completata" è TRUE, contestualmente creo un Alias che chiamo "Percentuale" dove il valore viene restituito da: [Espletate] / [Ricevute] * 100, a questo punto eseguo questa query :

    codice:
    SELECT TblRichieste.IdCircoscrizione, Count(TblRichieste.IdRichiesta) AS Ricevute,
    
     (
    
    SELECT Count(TblRichieste.IdRichiesta) 
     FROM TblRichieste WHERE TblRichieste.Completata = True
    
    ) AS Espletate, [Espletate]/[Ricevute]*100 AS Percentuale
    
    FROM TblRichieste
    
    GROUP BY TblRichieste.IdCircoscrizione;

    Il campo IdCircoscrizione mi restituisce le circoscrizione che hanno effettivamente ricevuto delle richieste (solo quelle che ne hanno ricevuta almeno una, sia completata che non), il Campo Ricevute mi restituisce l'effettivo numero delle richieste per circoscrizione, ma il campo espletate mi restituisce sempre lo stesso valore per ogni record, in questo caso il numero 5, e così non è, perchè invece i numeri sono differenti e non uguali per tutti, va da se che il campo percentuale non restituisce i valori corretti, per esempio nei record della 1, 2, e 5 circoscrizione le richieste ricevute sono 1,1, 2 e quelle espletate tutti 5, quindi è evidente che non si possono avere meno richieste ricevute rispetto a quelle espletate.

    ho provato e riprovato, ma non ne vengo a capo, non mi viene restituito nessun errore in fase di sintassi o di costrutto, eppure non riesco a capire dove sbaglio , mi date una mano a capire?

    Vi ringrazio

  2. #2
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Manca un pezzo di logica nella subquery. La colonna [Completata] deve essere giustamente True come da te scritto, ma gli devi anche dire che [IdCircoscrizione] deve essere uguale a [IdCircoscrizione] della query più esterna. Quando creo query di questo tipo, per comodità sfrutto gli alias anche sulle tabelle e non solo sulle colonne. Io imposterei la tua query così:
    codice:
    SELECT R1.IdCircoscrizione, Count(R1.IdRichiesta) AS Ricevute,
    
     (
    
    SELECT Count(R2.IdRichiesta) 
     FROM TblRichieste As R2 WHERE R2.Completata = True And R1.IdCircoscrizione = R2.IdCircoscrizione
    
    ) AS Espletate, [Espletate]/[Ricevute]*100 AS Percentuale
    
    FROM TblRichieste As R1
    
    GROUP BY R1.IdCircoscrizione;
    Così R1 ed R2 sono la medesima tabella, ma leggendo sai che R1 è la più esterna, mentre R2 è quella della subquery. Così scritta, dovrebbe restituirti tutte quelle completate a parità di [IdCircoscrizione]. Uso il condizionale perché non ho dati per fare test. :-)

  3. #3
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Manca un pezzo di logica nella subquery. La colonna [Completata] deve essere giustamente True come da te scritto, ma gli devi anche dire che [IdCircoscrizione] deve essere uguale a [IdCircoscrizione] della query più esterna. Quando creo query di questo tipo, per comodità sfrutto gli alias anche sulle tabelle e non solo sulle colonne. Io imposterei la tua query così:
    codice:
    SELECT R1.IdCircoscrizione, Count(R1.IdRichiesta) AS Ricevute,
    
     (
    
    SELECT Count(R2.IdRichiesta) 
     FROM TblRichieste As R2 WHERE R2.Completata = True And R1.IdCircoscrizione = R2.IdCircoscrizione
    
    ) AS Espletate, [Espletate]/[Ricevute]*100 AS Percentuale
    
    FROM TblRichieste As R1
    
    GROUP BY R1.IdCircoscrizione;
    Così R1 ed R2 sono la medesima tabella, ma leggendo sai che R1 è la più esterna, mentre R2 è quella della subquery. Così scritta, dovrebbe restituirti tutte quelle completate a parità di [IdCircoscrizione]. Uso il condizionale perché non ho dati per fare test. :-)

    Allora Sgrubak, Anziché volere visualizzare solo i dati delle richieste ricevute, ho pensato di visualizzare anche i record che non hanno mai avuto richieste, e così ho modificato il Join della query a Left su TblCircoscrizioni:

    codice:
    SELECT TblCircoscrizioni.ID, Count(TblRichieste.[IdRichiesta]) AS Ricevute, (SELECT Count(TblRichieste.IdRichiesta) 
    
     FROM TblRichieste WHERE TblRichieste.Completata = True And TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    
    ) AS Espletate, [Espletate]/[Ricevute]*100 AS Percentuale
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblRichieste.IdCircoscrizione = TblCircoscrizioni.ID
    GROUP BY TblCircoscrizioni.ID;
    e il tuo suggerimento sul passargli come parametro l' ID della circoscrizione è stato determinante, sinceramente non ci avevo neanche pensato lontanamente, davo per scontato che essendo sulla stessa tabella non necessitava.

    La query funziona bene adesso , MA... se nell'Alias Ricevute e nell'Alias Espletate i record che sono NULL mi restituiscono 0, lo stesso non succede nell'Alias percentuale, dove ovviamente " 0/0*100 " che dovrebbe darmi 0, anzi facendolo con la calcolatrice mi restituisce risultato indefinito, manco lo 0 riporta, mi restituisce viceversa questo valore "#Num!", è sicuramente un problema di formattazione, potrebbe bastare un IIF eventualmente?

  4. #4
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Quote Originariamente inviato da Diego1966 Visualizza il messaggio
    ...che dovrebbe darmi 0...
    Non si può dividere per 0. È matematicamente sbagliato, per quello ritorna l'errore.
    Quote Originariamente inviato da Diego1966 Visualizza il messaggio
    potrebbe bastare un IIF eventualmente?
    Dovrebbe aiutarti. Se il conteggio è 0 gli fai riportare un trattino o quel che ti pare.
    EDIT: ovviamente mi riferisco al conteggio 0 delle ricevute. Così se ne hai ricevute ma non ne hai espletate ti riporta correttamente 0.
    Ultima modifica di Sgrubak; 20-07-2019 12:50 

  5. #5
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Non si può dividere per 0. È matematicamente sbagliato, per quello ritorna l'errore.

    Dovrebbe aiutarti. Se il conteggio è 0 gli fai riportare un trattino o quel che ti pare.
    EDIT: ovviamente mi riferisco al conteggio 0 delle ricevute. Così se ne hai ricevute ma non ne hai espletate ti riporta correttamente 0.
    Ho aggiunto L'IIF ma continua a ritornarmi sempre "#Num!"

    codice:
    IIf([Espletate]/[Ricevute]*100="#Num!";0 & " %";[Espletate]/[Ricevute]*100 & " %")

    Apposto ho risolto con l'IIF il mio errore è passare all'IIF l'intero calcolo percentuale, invece prima avrei dovuto fare il controllo se i due alias Espletate e Ricevute fossero zero come valore, per cui va scritta in questo modo:


    codice:
    SELECT TblCircoscrizioni.ID, Count(TblRichieste.IdRichiesta) AS Ricevute, (SELECT Count(TblRichieste.IdRichiesta) 
    
     FROM TblRichieste WHERE TblRichieste.Completata = True And TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    
    ) AS Espletate, IIf([Espletate]=0 And [Ricevute]=0,0 & " %",[Espletate]/[Ricevute]*100 & " %") AS Percentuale
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID;
    in questo modo non restituisce più l'errore "#Num!" ma visualizza 0 %.

    Grazie per il tuo aiuto.
    Ultima modifica di Diego1966; 20-07-2019 13:59 

  6. #6
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Perché continui a voler dividere per 0.
    Devi avere
    codice:
     IIf([Ricevute]=0;0 & " %";[Espletate]/[Ricevute]*100 & " %")
    Altrimenti cerca di fare la divisione per valutare la condizione dell'IIF e si blocca restituendo l'errore.

  7. #7
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Perché continui a voler dividere per 0.
    Devi avere
    codice:
     IIf([Ricevute]=0;0 & " %";[Espletate]/[Ricevute]*100 & " %")
    Altrimenti cerca di fare la divisione per valutare la condizione dell'IIF e si blocca restituendo l'errore.
    Sono entrambi i valori che danno zero per questo [Espletate]=0 And [Ricevute]=0

  8. #8
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Un'ultima cosa e poi giuro che non rompo più le scatole, e se volessi filtrare ulteriormente la query per periodo?

    Ho provato a scrivere :

    codice:
    SELECT TblCircoscrizioni.ID, Count(TblRichieste.IdRichiesta) AS Ricevute, (SELECT Count(TblRichieste.IdRichiesta) 
    
     FROM TblRichieste WHERE Between TblRichieste.DataRichiesta And TblRichieste.DataRichiesta AS Periodo And TblRichieste.Completata = True And TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    
    ) AS Espletate, IIf([Espletate]=0 And [Ricevute]=0,0 & " %",[Espletate]/[Ricevute]*100 & " %") AS Percentuale
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    GROUP BY TblCircoscrizioni.ID;
    Ma continua a restituire errore, ho anche provato ad aggiungere l'HAVING Between TblRichieste.DataRichiesta And TblRichieste.DataRichiesta AS Periodo subito dopo il GROUP BY, ma niente, dove devo collocarlo questo filtro?


    Ho provato anche in questo modo:

    codice:
    SELECT TblCircoscrizioni.ID, Count(TblRichieste.IdRichiesta) AS Ricevute, (SELECT Count(TblRichieste.IdRichiesta) 
    
     FROM TblRichieste WHERE Between TblRichieste.DataRichiesta And TblRichieste.DataRichiesta AS Periodo And TblRichieste.Completata = True And TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione
    
    ) AS Espletate, IIf([Espletate]=0 And [Ricevute]=0,0 & " %",[Espletate]/[Ricevute]*100 & " %") AS Percentuale
    FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione WHERE (((TblRichieste.DataRichiesta) Between [DAL] And [AL])) AND TblRichieste.Completata = True AND  TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione 
    GROUP BY TblCircoscrizioni.ID;
    Ma mi restituisce dati sbagliati
    Ultima modifica di Diego1966; 20-07-2019 15:00 

  9. #9
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Usare la clausola HAVING è sbagliato, in quanto ti serve sulle funzioni di aggregazione. La keyword BETWEEN non ha la sintassi corretta. Infine non capisco perché ci sia quel [AS Periodo]. L'alias si specifica solo su colonne e tabelle che io sappia.

    Il filtro deve essere specificato sia nella query esterna che nella subquery. Se no estrai i dati con una logica ed effettui il conteggio con un'altra.

  10. #10
    L'avatar di Diego1966
    Diego1966 non è in linea Scolaretto
    Luogo
    Palermo
    Post
    131
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Usare la clausola HAVING è sbagliato, in quanto ti serve sulle funzioni di aggregazione. La keyword BETWEEN non ha la sintassi corretta. Infine non capisco perché ci sia quel [AS Periodo]. L'alias si specifica solo su colonne e tabelle che io sappia.

    Il filtro deve essere specificato sia nella query esterna che nella subquery. Se no estrai i dati con una logica ed effettui il conteggio con un'altra.
    Benissimo, adesso la query funziona per come si deve.

    codice:
    SELECT TblCircoscrizioni.ID, Count(TblRichieste.IdRichiesta) AS Ricevute, 
    
    (
           SELECT Count(TblRichieste.IdRichiesta) 
    
              FROM TblRichieste WHERE TblRichieste.Completata = True And TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione AND 
    
                  (((TblRichieste.DataRichiesta) Between [Data Iniziale] And [Data Finale]))
    
    ) AS Espletate, IIf([Espletate]=0 And [Ricevute]=0,0 & " %",[Espletate]/[Ricevute]*100 & " %") AS Percentuale
    
                        FROM TblCircoscrizioni LEFT JOIN TblRichieste ON TblCircoscrizioni.ID = TblRichieste.IdCircoscrizione WHERE
    
                           (((TblRichieste.DataRichiesta) Between [Data Iniziale] And [Data Finale]))
    
    GROUP BY TblCircoscrizioni.ID;
    Grazie.

    Buon Week End

+ 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