Gå til innhold

mysql: SELECT [siste X rader] SORTER eldste først


Anbefalte innlegg

Jeg har en tendens til å glemme sql mellom hver gang jeg bruker det. Trenger litt hjelp med et select-query. Det forklarest best med et eksempel med en enkel tabell:

create table tbl (id timestamp primary key, tekst varchar(20));
(Det er en forutsetning at de følgende insert queryene kjøres med minst 1 sek pause mellom hver pga timestamp som nøkkel.)
insert into tbl set tekst="a";
insert into tbl set tekst="b";
insert into tbl set tekst="c";
insert into tbl set tekst="d";
insert into tbl set tekst="e";

 

Jeg vil så hente ut de 3 siste postene sortert i samme rekkefølge som de ble lagt inn. Hvordan gjøres det?

Følgende kode tar med seg de rette postene, men sortert opp ned:

SELECT * FROM tbl ORDER BY id DESC LIMIT 3;

 

Jeg ønsker å sortere resultatet av query over, motsatt vei! Hva var trikset for slikt?

Endret av petterg
Lenke til kommentar
Videoannonse
Annonse

Edit: Gikk litt fort med forrige svar.

 

For det første, har du nøye tenkt gjennom det å bruke timestamp som nøkkel? For meg høres det ut som en særdeles dårlig idé. Videre er typisk sortering av data for presentasjon en jobb som normalt sett ikke bør være på databaseserveren.

 

Hvordan du løser problemet ditt på MySQL er jeg ikke sikker på.

Endret av roac
Lenke til kommentar

[offtopic]

ang å bruke å bruke timestamp som nøkkel: Når applikasjonen som legger inn nye data kan garantere at det går minst 2 sekunder mellom hver gang en ny rad legges til ser jeg ikke noe problem med det. Vil bruke den som nøkkel fordi det er den som brukes i samtlige filtreringer med WHERE. Innbiller meg at det vil gi en liten ytelsesforbedring å ha den som nøkkel i et slikt tilfelle.

Men, helt enig med deg - vanligvis vil man ikke bruke timestamp som nøkkel. [/offtopic]

 

Det er php som skal hente data fra databasen. Man kan selvsagt gjøre sorteringen i php, men mysql yter vel mye bedre på denne typen oppgaver i forhold til serverbelastning? (web og databaseserveren er samme maskin.)

Lenke til kommentar

Min første tanke var å bruke ASC istedenfor DESC, men da vil du jo få ut de tre første postene, så det hjelper ikke...

 

Men hva med å la php snu arrayet du har hentet ut med array_reverse()?

 

[offtopic]

Angående timestamp som nøkkel, jeg ville laget en funksjon som, hvis den ikke fikk lagt til data i databasen første gangen (fordi det allerede lå en lik timestamp der) prøver å legge til med timestamp+1, eventuelt flere ganger. Ting som "aldri vil skje", har en tendens til å skje likevel..

[/offtopic]

 

-Simen

Lenke til kommentar

Så vidt jeg husker er (var?) en av svakhetene i MySQL at du ikke enkelt kan velge de n siste radene i en spørring. Andre DBMSer lar deg gjøre noe slikt

SELECT * FROM tbl ORDER BY id LIMIT -3

for å oppnå det du ønsker.

 

Det nærmeste du kommer i MySQL er

SELECT * FROM tbl ORDER BY id LIMIT offset, 3

men da må du altså først beregne verdien offset. Hvilket betyr en ekstra spørring mot databasen hvis du ikke på annen måte vet nøyaktig hvor mange rader spørringen kommer til å resultere i.

 

Men jeg har ikke prøvd de nyeste versjonene av MySQL - det kan jo tenkes at de har lagt inn muligheten for negativ limit nå (selv om det ikke står nevnt i dokumentasjonen). Prøv selv :)

 

Ellers så er ikke

SELECT * FROM tbl ORDER BY id DESC LIMIT 3

så dumt. Det er ikke vanskeligere eller mer ressurskrevende å få PHP til å telle nedover i stedet for oppover. (Husk at du trenger ikke snu hele arrayet i PHP før du begynner å bruke det. Du trenger bare å jobbe bakfra i stedet for forfra).

Lenke til kommentar
[offtopic]

ang å bruke å bruke timestamp som nøkkel: Når applikasjonen som legger inn nye data kan garantere at det går minst 2 sekunder mellom hver gang en ny rad legges til ser jeg ikke noe problem med det. Vil bruke den som nøkkel fordi det er den som brukes i samtlige filtreringer med WHERE. Innbiller meg at det vil gi en liten ytelsesforbedring å ha den som nøkkel i et slikt tilfelle.

Men, helt enig med deg - vanligvis vil man ikke bruke timestamp som nøkkel. [/offtopic]

5491000[/snapback]

Har ikke MySQL støtte for indeksering?

Lenke til kommentar
Det er ikke vanskeligere eller mer ressurskrevende å få PHP til å telle nedover i stedet for oppover. (Husk at du trenger ikke snu hele arrayet i PHP før du begynner å bruke det. Du trenger bare å jobbe bakfra i stedet for forfra).

5492417[/snapback]

 

Det er jo et veldi godt poeng! Jeg var helt opphengt i manglende mysql kunnskap. Å jobbe bakfra i php vil jo være mye mindre ressurskrevende enn å la mysql kjøre sorteringsalgoritme på alt sammen.

Problemet i det spesielle tilfellet her er da løst.

 

Men jeg undrer fortsatt på om det finnes noen triks i mysql som tilsvarer LIMIT -X

Lenke til kommentar
[offtopic]

ang å bruke å bruke timestamp som nøkkel: Når applikasjonen som legger inn nye data kan garantere at det går minst 2 sekunder mellom hver gang en ny rad legges til ser jeg ikke noe problem med det. Vil bruke den som nøkkel fordi det er den som brukes i samtlige filtreringer med WHERE. Innbiller meg at det vil gi en liten ytelsesforbedring å ha den som nøkkel i et slikt tilfelle.

Men, helt enig med deg - vanligvis vil man ikke bruke timestamp som nøkkel. [/offtopic]

5491000[/snapback]

Har ikke MySQL støtte for indeksering?

5493024[/snapback]

 

jo...

Lenke til kommentar

Du kjører først en spørring som henter ut de dataene du skal

 

SELECT * FROM tbl ORDER BY id DESC LIMIT 3;

 

Deretter bruker du dataene derfra i en ny select...

 

SELECT * FROM (

SELECT * FROM tbl ORDER BY id DESC LIMIT 3;

) as myTempNameHere

ORDER BY id

 

Jeg ville heller ha kjørt sortering i databasen enn på applikasjonsserveren, jeg tror ikke du finner noe mer optimaliserte sorteringsalgoritmer enn de du finner i en database ;)

 

Eksempelet over funker ihvertfall i Postgres, tror MySql har støtte for indre selects på den måten også nå, ihvertfall i nyere (5+) versjoner

Lenke til kommentar
Du kjører først en spørring som henter ut de dataene du skal

 

SELECT * FROM tbl ORDER BY id DESC LIMIT 3;

 

Deretter bruker du dataene derfra i en ny select...

 

SELECT * FROM (

  SELECT * FROM tbl ORDER BY id DESC LIMIT 3;

) as myTempNameHere

ORDER BY id

 

Jeg er ganske sikker på at jeg har gjort noe i retning av det du gjør her før, og fått ønsket resultat, men dette funka ikke på mysql 4.1.25. Tipper det var 4.0.x da jeg gjorde dette sist. En eller annen mindre modifisering kan nok gjøre underverker.

 

Jeg ville heller ha kjørt sortering i databasen enn på applikasjonsserveren, jeg tror ikke du finner noe mer optimaliserte sorteringsalgoritmer enn de du finner i en database ;)

5494704[/snapback]

 

Ja, enig i det. Men som Mr. Floppy sa, så er dette et spesialtilfelle hvor man bare trenger å lese resultatet baklengs, og det tar jo mindre ressurser enn noen noen som helst av sortering. Riktig nok må hele resultatet legges i en buffer før man får brukt det videre, men det gjøres det jo uansett når man bruker php for å lese det ut.

Lenke til kommentar
  • 2 år senere...
Det er ikke vanskeligere eller mer ressurskrevende å få PHP til å telle nedover i stedet for oppover. (Husk at du trenger ikke snu hele arrayet i PHP før du begynner å bruke det. Du trenger bare å jobbe bakfra i stedet for forfra).

 

Det er jo et veldi godt poeng! Jeg var helt opphengt i manglende mysql kunnskap. Å jobbe bakfra i php vil jo være mye mindre ressurskrevende enn å la mysql kjøre sorteringsalgoritme på alt sammen.

Problemet i det spesielle tilfellet her er da løst.

 

Men jeg undrer fortsatt på om det finnes noen triks i mysql som tilsvarer LIMIT -X

 

Drar opp en gammel tråd her.

Hvordan løste du dette ved å la php jobbe baklengs?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...