26. oktober 2004 - 17:42Der er
32 kommentarer og 2 løsninger
avanceret order by
Hej Findes der en lækkerfræk måde at definere en avanceret sorteringsrækkefølge af en SQL forespørgsel på?
Hvis jeg nu har en lang liste over datoer og ønsker mit udtræk sorteret således at jeg først får alle poster med "dato i dag og en uge frem". Dereftefter får alle poster hvor dato er blank og til sidst får resten. Kan det lade sig gøre i en og samme forespørgsel? En alm order by hjælper jo ikke meget her.
Problemet med dette er at jeg får 3 recordsets ud af det i min asp kode, og jeg vil kun have et hvor det hele ligget samlet, men sorteret på nævnte måde. Tænkte på om der var en smart SQL ting man kunne lave fremfor at kode sig ud af det på en lidt halvklodset måde.
SELECT * FROM tabel ORDER BY CASE WHEN (TO_DAYS(CURDATE( )) - TO_DAYS(dato)) <= 7 THEN 1 WHEN dato IS NULL THEN 2 WHEN (TO_DAYS(CURDATE( )) - TO_DAYS(dato)) > 7 THEN 3 END
Hey arne_v Det ser sq smart ud. Det var noget i den stil jeg var ude efter. Jeg kan dog ikke helt for den til at virke. Det ser ud til at den bare ryster posen og spytter posterne ud lidt tilfældigt. Er du sikker på den er korrekt?
Jamen 9999-01-01 skal svare til at den er blank. Man har bare valgt at dette felt skal være udfyldt, så jeg kalder den 01-01-9999, hvis den ikke er defineret.
Giver det mening? Dvs. sorteringen skal ske således. 1 - alle dem der har dato i dag eller en uge frem 2 - alle dem der er 9999-01-01 3 - resten, sorteret efter dato - nyeste først
tja, det er ikke mit valg. Der er ønske om at feltet altid indeholder en datoværdi af en slags. Jeg kunne også have kaldt den 0000-00-00, men det er samme situation.
Uanset hvad, må løsningen da være den samme uanset om der står null eller 9999-01-01
Hej igen Det er klart at der er forskel på null og en dato. Tænkte jeg kunne løse det på denne måde: WHEN Saelger_Aftaledato = '9999-01-01' THEN 2
Den mystiske sortering kunne faktisk godt skyldes det manglende, Saelger_Aftaledato Det vil jeg lige teste når jeg er ved systemet igen, så vender jeg tilbage herefter :)
ORDER BY CASE WHEN (Saelger_Aftaledato >= CURDATE() and Saelger_Aftaledato < CURDATE() + INTERVAL 7 DAY) THEN 1 WHEN (Saelger_Aftaledato = '9999-01-01') THEN 2 else 3 END, Saelger_Aftaledato asc
Så virker det sq. Mange tak for hjælpen begge to. Jeg vil gerne fordele points mellem jer så smid et svar begge to.
Det tager dog en krig at foretage denne søgning når der er mange poster i tabellen. Meget længere tid end en almindelig "order by Saelger_Aftaledato" færdig slut.
Hvis du skal bruge den rigtigt meget, så kan du overveje at lave en kolonne med den værdi og så kun beregne den for en kolonne ved INSERT, så vil ORDER BY nok være noget hurtigere.
Du kan nok optimere en smule ved at sørge for at de oftest forekommende tilfælde står først i din CASE. F.eks, hvis '9999-01-01' er den oftest forekommende værdi, skal WHEN ... 2 stå først. Jeg kan forestille mig, at din WHEN ... 1 case er den *sjældnest* forekommende, så den bør være til sidst.
Men det er nok ikke mange splitsekunder du sparer på dén konto...
Det vil være den absolut største optimering du kan gøre.
At lave 9999-01-01 om til NULL vil give noget - men hvor meget ved jeg ikke. Og hvis du allerede har udviklet meget i din applikation, ville jeg personligt være forsigtig med at gå ind at ændre noget. Nogen gange må man bare leve med en uheldig designbeslutning :-(
Ups fik ikke lige svaret. Jeg har indexeret, så her kan jeg desværre ikke hente noget. Hvis ikke det vil give det store at rette dato til null er det vist ikke besværet værd.
Hvis du laver et felt sorthelp integer i tabellen og ved indsæt sætter den til rette værdi, så er det hurtigere a sortere efter.
Men det er noget vrøvl fordi feltets værdi skal ændres som tiden går.
Men så kunne så kunne du: - tilføje feltet sorthelp integer - køre et job lige efter midnat som sætter værdien af feltet med e UPDATE så vil en query ORDER BU sorthelp,dato nok køre noget hurtigere.
Giver selvfølgelig kun mening hvis queryen skal køres mange gang i løbet af dagen.
Men sommetider må man bøje reglerne lidt for at få den performance man har brug for.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.