19. juni 2006 - 09:55Der er
9 kommentarer og 1 løsning
Hent fra dato - 1 og frem
Jeg har en tabel med bl.a. et dato-felt. Fra en given dato vil jeg gerne have alle de records hvor:
1. datoen er null 2. den dato der er mindre end og ligger tættest på den givne dato 3. alle datoer der ligger efter den givne dato:
given dato (+) ----------------+--------------------- (-) o-----------+--------------------- (+) 0-----+--------------------- (+) o--------------- (+) o--------
Resultat: 4 records
Ikke det helt idelle resultat da recorden med null i dato-feltet kommer med selvom der faktisk er en record med med dato ældre end den givne. Den burde overstyre. Jeg kan eventuelt sortere den fra efterfølgende. Det bedste resultat er dette:
given dato (-) ----------------+--------------------- (-) o-----------+--------------------- (+) 0-----+--------------------- (+) o--------------- (+) o--------
Resultat: 3 records
Databasen er Interbase/Firebird, men skal helst være platformuafhængig da det snart skal porteres til mssql. Da der tilføjes mange records til tabellen er det ikke praktisk at hente alle ind og lave en sortering bagefter. Det vil snart blive sløvt.
Er der en sql-haj der kan brygge sådan en query sammen?
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
Hov der var lige noget jeg havde overset, nemlig at i 2) skriver at datoen skal være mindre end og tættest på den givne dato:
select * from dinTabel where dato = NULL OR dato > varDato union all select top 1 * from dinTabel where dato < varDato order by datediff(day, dato, varDato)
Desværre er "top" ikke med i de databaser jeg bruger. Det havde jeg prøvet, men glemt at nævne. Funktionen DateDiff forstår jeg ikke helt - hvad er grunden til den?
I øvrigt kan jeg ikke hitte ud af at få en "order by" smækket på. Resultatet blev derfor følgende:
select * from ydtaksttype where (dato is null or dato > '06-15-2006') and debid=8 union select * from ydtaksttype where dato < '06-15-2006' and debid=8
Så vidt jeg kan se skal det ikke være en "union all" da de to selects' kan levere overlappende recordset. Det havde været rart med en "top".
I øvrigt skulle tjekket for null have været omvendt. Hvis en record havde en null-dato men, at der fandtes dato-records ældre end den givne dato, skulle scriptet vælge disse. Det falder på, at man tilsyneladende ikke kan sortere sit sub-resultatsæt på dato og bruge "top"'en sammen med det.
select * from ydtaksttype where dato > '06-15-2006' and debid=8 union select * from ydtaksttype where (dato is null or dato < '06-15-2006') and debid=8
jamen skulle det ikke snart porteres til MSSQL :-)
Datediff anvender jeg til at finde ud af forskellen mellem to datoer. Jeg laver en order by på denne og snupper den første, idet denne ligger tættest på den givne dato.
I Firebird er der faktisk muligt at lave "select first 1 ..." som jeg må antage gør det samme som "top" - men desværre findes den funktionalitet ikke i Interbase som vi også bruger.
Hvis det kan hjælpe på opgaven så har jeg nu gjort fradato-feltet tvungent. Ikke noget med at lede efter null-felter.
Hvad datefiff angår så kan jeg ikke helt se forskellen mellem "order by fradato" og så din funktion.
Ved du om MSSQL har en "COMPUTED BY" mulighed (i CREATE TABLE)? Det kan måske løses vha. et beregnet felt. Ret smart om man kunne kalde en procedure den vej fra, men det set det dog ikke ud til. En select er dog mulig og hvad sker der med et resultat der returnerer flere records. Vil Interbase/Firebird/MSSQL så vælge den første værdi eller vil de raise en exception... Det er noget jeg skal prøve.
Der er ikke nogen forskel - bare glem det der med datediff, det er levn fra mit første indlæg hvori jeg havde fejlfortolket dit spm. Så fradato er helt fint at anvende.
beef12: Jeg har måttet programmere mig ud af det, ikke optimalt, men jeg kan stå inde for det. I stedet for at du skal ligge vågen om natten for at finde en løsning så synes jeg at vi skal lukke spørgsmålet. Da opgaven ikke er blevet løst vil det være forkert at give fuld pointsantal, men smider du et svar, så kan du få de 25 for dit besvær. Håber det er OK.
Helt fint - jeg har ikke løst dit problem, så snup du bare alle points :-)
Og held og lykke med projektet.
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.