Query di estrazione righe



  • Query di estrazione righe
    di Captain Harlock (utente non iscritto) data: 18/08/2016 22:58:38

    Il quesito non è facile.
    Semplificando, ho dei dipendenti che periodicamente vengono monitorati e i risultati del monitoraggio finiscono in un documento individuale registrato con data, esito e un numero progressivo di revisione.
    I dipendenti, per pensionamento o nuova assunzione, hanno lo status di “attivi” o “non attivi”.
    In Access ho realizzato una tabella che raccoglie tutte (e molte altre) informazioni.
    Dalla tabella devo ricavare le informazioni legate all’ultima revisione di quel documento individuale dei soli dipendenti “attivi”.

    Esempio della tabella:

    ID_QUESTIONARIO MATRICOLA COGNOME ATTIVO DATA_RILEVAZIONE REVISIONE ESITO
    1 100 TOPOLINO 1 1-5-2014 0 1
    2 110 PIPPO 1 7-5-2014 0 0
    3 120 GAMBADILEGNO 0 8-9-2014 0 0
    4 100 TOPOLINO 1 12-8-2015 1 0
    5 110 PIPPO 1 4-2-2015 1 1
    6 130 MINNI 1 4-1-2016 0 1
    7 100 TOPOLINO 1 10-1-2016 2 1
    8 120 GAMBADILEGNO 0 1-6-2015 1 0
    9 140 TRUDY 0 2-4-2016 0 0
    10 110 PIPPO 1 6-7-2016 2 1
    11 110 PIPPO 1 1-8-2016 3 0

    Voglio ottenere una nuova tabella il cui risultato sia questo:

    ID_QUESTIONARIO MATRICOLA COGNOME ATTIVO DATA_RILEVAZIONE REVISIONE ESITO
    6 130 MINNI 1 4-1-2016 0 1
    7 100 TOPOLINO 1 10-1-2016 2 1
    11 110 PIPPO 1 1-8-2016 3 0

    La mia soluzione non funziona perché estrae tutti i dati mentre io voglio solo quelli col numero di revisione più alto:
    Codice:

    SELECT ID_QUESTIONARIO, matricola, cognome, attivo, data_rilevazione, Max(revisione) AS rev, esito
    FROM tbQuestionari
    GROUP BY ID_QUESTIONARIO, matricola, cognome, attivo, data_rilevazione, esito, revisione
    ORDER BY cognome;

    Come costruire la query?



  • di Raffaele_53 data: 19/08/2016 06:53:19

    Questo forum è per Excel, comunque "usavo Access" e se posso rispondo.
    Di norma servirebbe anche un piccolo allegato senza dati personali.

    >>>solo quelli col numero di revisione più alto
    Se il dato revisione è subito dopo la data, credo che >>>6 130 MINNI 1 4-1-2016 0 1 sia errato. mi sembra più giusta questa lista (scegliendo numeri alti "tra" i due & tre):
    7 100 TOPOLINO 1 10-1-2016 2 1
    11 110 PIPPO 1 1-8-2016 3 0

    Ps. Presumo che intendi "più alti per ogni NOME", però mancherebbe GAMBADILEGNO & TRUDY nella lista?



  • di Vecchio Frac data: 19/08/2016 08:37:57

    @Captain Harlock
    Come dice Raffaele un file di esempio sarebbe gradito, è difficile ricostruire lo scenario ricopiandosi i dati che hai proposto (soprattutto ci vuole del tempo).
    Comunque, la mia domanda riguarda ID_QUESTIONARIO: è la chiave primaria? univoca? ti serve nell'estrazione dei dati o basta l'elenco dei dipendenti DISTINCT?

    @Raffaele
    cit. "Questo forum è per Excel"
    ---> Sì in linea di massima, ma possiamo parlare anche di sviluppo in Access se riguarda programmazione (con e senza VBA). Diciamo piuttosto che Captain Harlock ha sbagliato sezione, io avrei postato nell'altra, più generica.





  • di patel data: 19/08/2016 09:00:22

    il banner blu in alto recita:
    Forum di Excel e VBA, per condividere esperienze e risolvere problemi su:
    Excel, Word, Access, Power Point, Microsoft Office, macro, Visual Basic e Visual Studio.





  • di Vecchio Frac data: 19/08/2016 09:34:40

    Sì, è solo questa sezione in cui ha postato l'OP che è sbagliata.
    Ma pazienza non è una cosa così grave :)

    Nel merito mi ricordo che qualche tempo fa avevo affrontato una cosa simile e avevo risolto con due query, con una ricavando il valore massimo del campo che interessa dalla tabella per ogni id, con l'altra usando i risultati della query come confronto per l'inner join.






  • di captain harlock (utente non iscritto) data: 19/08/2016 10:32:06

    Io devo estrarre le righe per ogni matricola con il numero di revisione più alto. Non c'entra niente la data! Il risultato che ho postato io è quello corretto.
    id_questionario è la chiave primaria ed è ovviamente univoca e serve nel risultato (come quello che ho postato!!).
    Ce la fate? mi servirebbe
    grazie



  • di scossa data: 19/08/2016 10:33:17

    cit.: "Nel merito mi ricordo che qualche tempo fa avevo affrontato una cosa simile e avevo risolto con due query, con una ricavando il valore massimo del campo che interessa dalla tabella per ogni id, con l'altra usando i risultati della query come confronto per l'inner join"

    Come ho già detto, utilizzo T-SQL più che access, ma la query (access) sotto dovrebbe funzionare.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    SELECT id_questionario, anag.matricola, cognome, attivo, data_rilevazione, revisione, esito
    FROM tbQuestionari AS Anag 
    INNER JOIN (SELECT DISTINCT matricola, max(data_rilevazione) AS LastRil 
    FROM tbQuestionari  WHERE ATTIVO = 1 GROUP BY matricola)  AS LastAgg 
    ON (anag.data_rilevazione = lastAgg.LastRil) AND (anag.matricola = LastAgg.matricola)
    ORDER BY id_Questionario;



  • di Vecchio Frac data: 19/08/2016 10:44:55

    Ahhhh non avevo capito che c'era urgenza... la soluzione è qui: regolamento di utilizzo. In particolare i punti 8 e 9.

    @scossa
    cit. "Come ho già detto utilizzo T-SQL"
    ---> Non ricordavo... ma Transact SQL non dovrebbe essere troppo diverso.
    Magari provo, mi incuriosisce (nel frattempo sto cercando la mia soluzione).





  • di captain harlock (utente non iscritto) data: 19/08/2016 10:55:35

    Ultimamente incontro tanti moderatori simpatici, adesso anche il Moderatore Spiritoso.
    La query di scossa non produce nessun risultato, ma grazie lo stesso almeno ho qualcosa di diverso da confrontare con la mia.



  • di Vecchio Frac data: 19/08/2016 11:00:58

    @Captain Harlock
    cit. "adesso anche il Moderatore Spiritoso. "
    ---> Ci sono così tanti musoni in giro che ogni tanto ridere fa bene ^_^ anche tu dovresti togliere il mantello nero e scoprirai che il cuore bianco è (LOL forse la capisci solo tu)

    Comunque la query di scossa funziona (ed a un passo solo, mentre io avevo ideato una soluzione son la sottoquery separata). Funziona bene, soltanto che così com'è non produce in effetti alcun risultato, c'è una piccolissima, banale correzione da fare (@scossa hai fatto apposta?).
    Ma ti lascio il piacere di scovartela :P





  • di scossa data: 19/08/2016 11:10:33

    cit. V.F.: "---> Non ricordavo... "

    Nemmeno io


    cit. Captain Harlock: "La query di scossa non produce nessun risultato..."
    a me, sulla tabella ricostruita in base al tuo esempio, restituisce il risultato che hai indicato:



    ABCDEFG
    1id_questionariomatricolacognomeattivodata_rilevazionerevisioneesito
    26130MINNI104/01/2016 00:0001
    37100TOPOLINO110/01/2016 00:0021
    411110PIPPO101/08/2016 00:0030


    Ma vedo che mantieni il tuo atteggiamento altezzoso ed irrispettoso verso gli altri interlocutori ....


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    SELECT Anag.id_questionario, Anag.matricola, Anag.cognome, Anag.attivo, Anag.data_rilevazione, Anag.revisione, Anag.esito
    FROM tbQuestionari AS Anag INNER JOIN 
    (SELECT DISTINCT matricola, max(id_questionario) AS LastRil FROM tbQuestionari WHERE ATTIVO = 1 GROUP BY matricola)  AS LastAgg 
    ON (Anag.matricola = LastAgg.matricola) AND (Anag.id_questionario = LastAgg.LastRil)
    ORDER BY Anag.id_questionario;
    



  • di Vecchio Frac data: 19/08/2016 11:34:58

    @scossa
    Che tipo di dati hai impostato per il campo "attivo" ?
    In Access il tipo di dati Sì/No in quanto booleano potrebbe essere tradotto con l'intero, ma in Jet SQL di Access l'intero per True è -1, non 1 ... con l'impostazione di [attivo] a numerico e quindi 0/1 allora ok, nessun problema :)

    Per la cronaca e per quanto possa servire, allego la mia soluzione su due query separate (ma mi piace di più quella unica).
     
    QUERY1
    ---------
    SELECT matricola, Max(revisione) AS rev
    FROM tbQuestionari
    WHERE attivo=True
    GROUP BY matricola
    ORDER BY Val(matricola);
    
    QUERY2
    ---------
    SELECT id_questionario, tbQuestionari.matricola, cognome, attivo, data_rilevazione, revisione, esito
    FROM tbQuestionari 
    INNER JOIN [query1] ON (tbQuestionari.matricola=[query1].matricola) AND (tbQuestionari.revisione=[query1].rev)
    WHERE attivo = True
    ORDER BY id_questionario;
    






  • di scossa data: 19/08/2016 11:40:17

    cit. V.F.: "Che tipo di dati hai impostato per il campo "attivo" ? "

    Numerico, generico (ho copiato da Excel in cui avevo incollato l'esempio dell'OP).


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.
    (George Bernard Shaw)



  • di Vecchio Frac data: 19/08/2016 11:53:58

    Ecco il motivo è quello allora, lui ha un campo booleano (cosa che faccio anch'io veramente per questo tipo di informazioni, come attivo, in servizio, presente/assente, archiviato, ecc).
    La tua query funziona benissimo su un campo booleano impostando "WHERE attivo=-1".
    Infatti me la tengo stretta :)





  • di scossa data: 19/08/2016 12:44:34

    cit. V.F.: "La tua query funziona benissimo su un campo booleano impostando "WHERE attivo=-1"."

    Per non preoccuparsi del tipo di campo, si può scrivere "WHERE attivo<>0", perché l'unica cosa sicura tra i vari SQL e VBA è che False è 0 quindi tutto ciò che è <> 0 è considerato True:



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.
    (George Bernard Shaw)

     
    SELECT Attivo, IIf(Attivo,True,False) AS STATO, IIf(Attivo<>0,"VERO","FALSO") AS DES_STATO
    FROM tbQuestionari;
    



  • di Vecchio Frac data: 19/08/2016 14:15:29

    Io pensavo anche a qualcosa tipo "NOT attivo". E' un po' il problema di conversione di tipi che ho anche in python (ma lì sto litigando furiosamente con le date, assicuro che migrare db Jet in SQLite non è facile almeno non per me che ho iniziato a sbattere il muso sui formati data).





  • di captain harlock (utente non iscritto) data: 19/08/2016 14:25:12

    Sì adesso funziona!!
    Bravi grazie mille soprattutto a scossa, sei meglio di altri (non parlo di qui).
    Ok alla prossima



  • di scossa data: 19/08/2016 14:33:52

    cit. V.F.: "... sto litigando furiosamente con le date, assicuro che migrare db Jet in SQLite non è facile ...."

    Come ti capisco!
    Il formato delle date è sempre un problema, ma quando si tratta di far colloquiare tra loro due formati DB diversi diventano problematici anche i formati numerici più semplici: non so se hai mai usato SAS, ma ti assicuro che se devi trasferire una tabella da SAS a SQL Server non puoi dare niente per scontato.

    cit. C.H.: "Sì adesso funziona!!"
    Bene.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 19/08/2016 14:53:24

    cit. " se devi trasferire una tabella da SAS a SQL Server non puoi dare niente per scontato. "
    ---> Lo credo bene! No non mastico l'argomento. Mi sto solo scontrando con problemi di migrazione da Access a python (e forse non mi lasceranno nemmeno installarlo sui miei pochi client, l'Azienda è un po' rigida su questo). Però ho visto differenze di linguaggio, al limite dell'incompatibilità di tipi, tra Jet SQL e SQLite che non pensavo potessero esserci... proprio da perdita di dati. Vabbè.
    Comunque se ho bisogno (anche per tradurre le query) ti faccio un fischio e approfitto ;)





  • di scossa data: 19/08/2016 16:08:33

    cit. V.F.: "Comunque se ho bisogno (anche per tradurre le query) ti faccio un fischio e approfitto ;) "

    Per quel che sono in grado, volentieri!



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.
    (George Bernard Shaw)



  • di Raffaele_53 data: 19/08/2016 22:03:36

    Premesso che sono autodidatta e da 10 anni non l'ho uso più.
    L'allegato con 2007 (molto differente dal 2000/2003), dove si visualizza i dati che richiedeva.

    Ps. Qualche piccolissima frase di codice l'avevo scritto, di solito erano solo dentro query e maschere.
    Non capisco dove inserite i "Vostri codici", per visualizzare il risultato.
    In pratica, come fatte Voi?




  • di Vecchio Frac data: 19/08/2016 22:23:48

    Ciao Raffaele,
    poichè si tratta di una simulazione con una query diretta, non serve attivare codice VBA, basta (ovviamente oltre ad avere la tabella) creare una Query con Crea >> Struttura query, quindi chiudere la proposta di riferimento a tabella esistente che fa Access e selezionare il pulsantone "SQL" a sinistra del ribbon del menu. Qui incolli (o scrivi) la query che puoi, subito dopo "Eseguire".
    Access è cambiato abbastanza dalle prime versioni (io ho imparato qualcosa con Access 97 ma poi ho notato profonde trasformazioni).





  • di Raffaele_53 data: 19/08/2016 22:45:58

    Grazie VF
    In pratica mentre io facevo la query fisicamente con le varie condizioni (Vero, Max).
    In SQL, automaticamente viene scritto il tutto. Una specie di registratore Excel...



  • di Vecchio Frac data: 19/08/2016 23:12:22

    Sì esatto Raffaele! Hai capito perfettamente e il paragone è giusto! Tu ti riferisci al modo visuale di Access di costruire le viste (come si chiamano normalmente le query, cioè le interrogazioni). Il motore Jet SQL di Access traduce le operazioni fatte col mouse nelle corrispondenti istruzioni SQL, a volte in modo anche ridondante (proprio come accade con i registratori di macro).
    Però puoi sempre scrivertela tu ;)