Modello di progettazione MS-Access per l'ultimo valore di un raggruppamento

StackOverflow https://stackoverflow.com/questions/47413

  •  09-06-2019
  •  | 
  •  

Domanda

È comune avere una tabella in cui, ad esempio, i campi sono conto, valore e ora.Qual è il modello di progettazione migliore per recuperare l'ultimo valore per ciascun account?Sfortunatamente l'ultima parola chiave in un raggruppamento fornisce l'ultimo record fisico nel database, non l'ultimo record in base a qualsiasi ordinamento.Ciò significa che IMHO non dovrebbe mai essere usato.I due approcci goffi che utilizzo sono un approccio sottoquery o una query secondaria per determinare l'ultimo record e quindi unirsi alla tabella per trovare il valore.Non esiste un approccio più elegante?

È stato utile?

Soluzione

L'opzione subquery mi sembra la migliore, qualcosa come il seguente pseudo-sql.Potrebbe essere possibile/necessario ottimizzarlo tramite un join, che dipenderà dalle capacità del motore SQL.

select * 
from table 
where account+time in (select account+max(time) 
                       from table 
                       group by account 
                       order by time) 

Altri suggerimenti

Questo è un buon trucco per restituire l'ultimo record in una tabella:

SELECT TOP 1 * FROM TableName ORDER BY Time DESC  

Guardare questo sito per maggiori informazioni.

non potresti fare:

select account,last(value),max(time)
from table
group by account

L'ho testato (sicuro che si tratti di un set di dischi molto piccolo, quasi banale) e ha prodotto risultati adeguati.

Modificare:

anche questo non funziona dopo altri test.Ho fatto un bel po' di programmazione dell'accesso in una vita passata e ho la sensazione che ci sia un modo per fare ciò che chiedi in 1 query, ma al momento sto disegnando uno spazio vuoto.Scusa.

@Tom potrebbe essere più facile per me in generale fare la query "in" che hai suggerito.Generalmente faccio qualcosa del genere

select T1.account, T1.value
from table T as T1
where T1 = (select max(T2.time) from table T as T2 where T1.account = T2.Account) 

Dopo letteralmente anni di ricerche ho finalmente trovato la risposta al link sottostante n. 3.Le sottoquery di cui sopra funzioneranno, ma sono molto lente, debilitanti per i miei scopi.

La risposta più popolare è una query a tre livelli:Il 1° livello trova il massimo, il 2° livello ottiene i valori del campo in base alla prima query.Il risultato viene quindi unito come tabella alla query principale.Veloce ma complicato e dispendioso in termini di tempo da codificare/mantenere.

Questo collegamento funziona, funziona ancora abbastanza velocemente e richiede molto meno lavoro da codificare/mantenere.Grazie agli autori di questo sito.

http://access.mvps.org/access/queries/qry0020.htm

@shs
sì, quella select last(value) DOVREBBE funzionare, ma non funziona...La mia comprensione, anche se non riesco a produrre una fonte autorevole, è che last(value) fornisce l'ultimo record fisico nel file di accesso, il che significa che potrebbe essere il primo in termini temporali ma l'ultimo fisicamente.Quindi non penso che dovresti usare last(value) per qualcosa di diverso da una riga casuale davvero pessima.

Sto cercando di trovare la data più recente in un gruppo utilizzando il generatore di query di Access 2003 e ho riscontrato lo stesso problema tentando di utilizzare LAST per un campo data.Ma sembra che l'utilizzo di MAX trovi la data più recente.

Forse il seguente SQL è goffo, ma sembra funzionare correttamente in Access.

SELECT
    a.account,
    a.time,
    a.value
FROM
    tablename AS a INNER JOIN [
        SELECT
            account,
            Max(time) AS MaxOftime
        FROM
            tablename
    GROUP BY
        account
    ]. AS b
    ON
        (a.time = b.MaxOftime)
        AND (a.account = b.account)
;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top