Ottenere l’ultimo record da mysql

Sto usando mysql e sto affrontando qualche problema. Voglio recuperare l’ultima riga inserita.

<>

Di seguito è come ho creato la tabella.

create table maxID (myID varchar(4))

Ho inserito quattro valori come sotto

     insert into maxID values ('A001') insert into maxID values ('A002') insert into maxID values ('A004') insert into maxID values ('A003') 

    Quando select myID, last_insert_id() as NewID from maxID , ottengo l’output come sotto

     myId NewID A001 0 A002 0 A004 0 A003 0 

    Quando ho provato sotto il codice,

    select myId, last_insert_id() as NewID, @rowid:[email protected]+1 as myrow from maxID, (SELECT @rowid:=0) as init

    Ottengo l’output come di seguito.

     myId NewID rowid A001 0 1 A002 0 2 A004 0 3 A003 0 4 

    Tuttavia quando uso il codice select myId, last_insert_id() as NewID, @rowid:[email protected]+1 as myrow from maxID, (SELECT @rowid:=0) as init where @rowid = 4 , ottengo errore come Uknown column 'myrow' in where clause

    Quando uso where @rowid=4 , non ottengo alcun dato nelle tabelle.

    Link per giocare con i dati

    Nota: qui sto usando 4 solo per ottenere l’output desiderato. Più tardi posso ottenere questo da una query (select max(rowid) from maxID)

    Per favore suggeriscimi cosa devo fare se voglio vedere solo l’ultimo record, ad esempio A003 .

    Grazie per il tuo tempo.

    Aggiornare:

    Ho già milioni di dati nella mia tabella, quindi non posso aggiungere nuove colonne come suggerito di seguito.

    Sembra che a SELECT non sia garantito il ritorno di righe in un ordine specifico (ovviamente senza usare una clausola ORDER BY ).

    Secondo lo standard SQL-92 (p.337):

    Se non è specificato un , la tabella specificata dalla è T e l’ordine delle righe in T dipende dall’implementazione.

    Ok, MySQL non è completamente compatibile con SQL-92, ma questo è un suggerimento serio.

    Laurynas Biveinis (apparentemente affiliata a Percona ) afferma anche :

    L’ordine delle righe in assenza della clausola ORDER BY (…) potrebbe essere diverso a causa della fase lunare e questo è OK.

    Il manuale MySQL dice di InnoDB:

    InnoDB ordina sempre le righe della tabella in base a [a PRIMARY KEY o NOT NULL UNIQUE index] se ne è presente una.

    Per quanto mi riguarda, presumo che MySQL possa anche riordinare le righe dopo una OPTIMIZE TABLE o persino riutilizzare gli spazi vuoti dopo molte eliminazioni e inserimenti (ho cercato di trovare un esempio di questo e ho fallito finora).

    Data la struttura della tabella, la linea di fondo è, sfortunatamente, che così tanti fattori potrebbero aver alterato l’ordine delle righe; Non vedo alcuna soluzione per determinare in modo affidabile l’ordine in cui sono stati inseriti. A meno che tu non abbia conservato tutti i log binari da quando hai creato la tabella, ovviamente;)

    Tuttavia, potresti comunque voler aggiungere una colonna di sequence al tuo tavolo. Alle righe esistenti verrebbe assegnato un numero di sequenza probabilmente impreciso, ma almeno le righe future saranno correttamente sequenziate.

     ALTER TABLE maxID ADD sequence INT DEFAULT NULL; ALTER TABLE maxID ADD INDEX(sequence); ALTER TABLE maxID MODIFY sequence INT AUTO_INCREMENT; 

    http://sqlfiddle.com/#!2/63a8d/1

    Quasi fatto. Riuscire a ottenere l’ordine di inserimento. Così:

     select myId, @rowid:[email protected]+1 as myrow from maxID, (SELECT @rowid:=0) as init ORDER BY myrow desc LIMIT 1; 

    Nella mia console ottengo il seguente:

     mysql> select myId, @rowid:[email protected]+1 as myrow from maxID, (SELECT @rowid:=0) as init ORDER BY myrow desc LIMIT 1; +------+-------+ | myId | myrow | +------+-------+ | A003 | 4 | +------+-------+ 1 row in set (0.00 sec) 

    dimostrazione

    AGGIORNARE

    Yak ha ragione. La mia soluzione non è deterministica. Forse funziona per una piccola quantità di record. Ho trovato tonnellate di post inaware inaffidabilità dell’ordinamento predefinito di un’istruzione SELECT ( qui ad esempio ). Prossimi passi:

    • In quali condizioni l’ordinamento SELECT predefinito corrisponde all’ordine di inserimento?
    • È ansible ottenere l’ultimo record inserito in una tabella senza un ID incrementale o un timestamp di inserimento?

    So che non è una risposta, ma affermare il problema limita il problema.

    Dal tuo script di inserimento, A004 non è l’ultimo record inserito. È il terzo. Se si desidera ottenere l’ultimo record in ordine alfabetico (quale A004 è), è necessario utilizzare

     select myID from maxID order by myID desc limit 1 

    Se vuoi l’ultima riga inserita, perché non usi semplicemente aggiungere una colonna autoincrement al tuo tavolo? Questo è il punto di quei tipi di colonne. La colonna di autoincremento non deve essere il PK (dovrebbe essere, ma non è necessario se non si ha la scelta).

    Come menzionato nella guida di MySQL per last_insert_id , puoi utilizzarlo solo con ** colonne di incremento automatico. Ciò significa che non puoi fare in modo che MySQL trovi la riga inserita più recentemente, a meno che tu non sappia qualcosa sull’ordine degli ID. Se sono ordinati come suggerisce il tuo esempio, puoi utilizzarli

     SELECT * FROM maxID WHERE myId = max(myId) 

    Ma suggerisco di aggiungere una colonna di autoincremento alla tabella e quindi usare = last_insert_id() nella tua clausola WHERE . Vedi anche questa pagina per informazioni su come ottenere l’ultimo ID.

    last_insert_id non funziona perché restituisce solo l’ultimo valore generato da un campo di incremento automatico. Comunque penso che la soluzione potrebbe essere sulla strada giusta. Vorrei suggerire di aggiungere un’altra colonna che è un intero autoincremento. È quindi ansible inserire dati e recuperare la riga appena inserita selezionare last_insert_id (). Per recuperare la riga più recente (inserita da qualsiasi processo) seleziona il numero massimo per la nuova colonna, o ordina per essa la desc.

    Se si desidera utilizzare la colonna varchar, è ansible eseguire un ordinamento alfabetico, ma ciò non garantisce che sarà l’ultima riga inserita o la riga inserita più di recente.

    L’altra soluzione a cui riesco a pensare può fare quello che ti serve è creare una procedura memorizzata che crea la riga, la inserisce nella tabella e poi la restituisce.

    L’utilizzo di @rowid è semplicemente il conteggio delle righe di ordine che ti vengono restituite. Non vi è alcuna garanzia che vengano restituiti nell’ordine dal più vecchio al più recente. Ci sono una varietà di cose che possono influenzare l’ordine in cui sono archiviate le righe.

    Si prega di utilizzare la seguente query.

     Select * from maxID order by myId desc limit 1,1;