petterg Skrevet 24. januar 2006 Del Skrevet 24. januar 2006 (endret) 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 24. januar 2006 av petterg Lenke til kommentar
roac Skrevet 24. januar 2006 Del Skrevet 24. januar 2006 (endret) 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 24. januar 2006 av roac Lenke til kommentar
petterg Skrevet 24. januar 2006 Forfatter Del Skrevet 24. januar 2006 [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
tussiesel Skrevet 24. januar 2006 Del Skrevet 24. januar 2006 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
Mr. Floppy Skrevet 24. januar 2006 Del Skrevet 24. januar 2006 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
roac Skrevet 24. januar 2006 Del Skrevet 24. januar 2006 [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
petterg Skrevet 25. januar 2006 Forfatter Del Skrevet 25. januar 2006 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
mikaelandre Skrevet 25. januar 2006 Del Skrevet 25. januar 2006 [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
blackbrrd Skrevet 25. januar 2006 Del Skrevet 25. januar 2006 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
petterg Skrevet 25. januar 2006 Forfatter Del Skrevet 25. januar 2006 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
MirusMentis Skrevet 20. desember 2008 Del Skrevet 20. desember 2008 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). <{POST_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 Drar opp en gammel tråd her. Hvordan løste du dette ved å la php jobbe baklengs? Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå