19. december 2014 - 21:06Der er
18 kommentarer og 1 løsning
Hjælp til SQL query
Jeg har en tabel med følgende kolonner.
id_nr prv_nr navn dato 1 100 A 1 100 B 2 101 D 2 102 A 2 103 A 3 104 G 4 105 A 4 105 E
Jeg har brug for at lave en ny tabel. Jeg skal kun have de rækker med hvor det er første gang et givet 'navn' forekommer for et givet id_nr, eller hvis der er mere en x dage mellem at det samme 'navn' forekommer. Den kan jeg ikke lige selv greje. Nogen kloge hoveder derude?
Det vil nok være nemmere, hvis du gør det tydeligere hvad du ønsker at opnå. Kan du for eksempel brede tabellen ud og så fortælle hvilke rækker det er du vil bevare og hvilke du vil skippe?
OK, jeg prøver lige igen. Kan nu ikke forklare det så meget anerledes.
Jeg har 4 kolonner: id_nr, prv_nr, navn og dato. Jeg ønsker at bevare de rækker, hvor 'navn' forekommer første gang hos et 'id_nr'. Rækken skal også bevares hvis der er mere end x dage mellem at det samme 'navn' forekommer hos et 'id_nr'.
#5, ja, det kan vel best (eller kun) klares i applikationen, men jeg forsøgte at forstå problemstillingen entydigt, så jeg måske kunne være med til at foreslå hvordan der kunne filtreres. For eksempel står det mig ikke klart, hvad der skal ske, hvis der for en id er adskillige forekomster af det samme navn der er x dage fra det første. Men hcthorsen, det vil du ikke ind på. Det er da i orden, så lader jeg det ligge.
Ad #5: Du har nok ret. Hvis ikke du kan arne, så er der nok ingen der kan fixe det i SQL.
Ad #6: Jo, jeg vil skam gerne præcisere. Det drejer sig om bakteriedyrkninger (prv_nr) hos patienter (id_nr). Bakterierne har et navn (navn). Det er ikke interessant hvis den samme bakterie forekommer 4 gange samme dag, eller mange gange med få dages mellemrum. Derimod er det interessant hvis bakterien dukker op igen efter fx. 14 dage. Jeg har endnu ikke lagt mig fast på hvor mange dage der skal gå, så lad os bare kalde det x dage. Jeg vil altså gerne have sorteret lidt i mine data, så jeg kun har første gang en bakterie findes, eller hvis den dukker op igen efter x dage (og så igen efter x dage). Giver det mening?
En ting du ikke forklarede entydigt er hvad du vil bevare, hvis du har for eksempel følgende rækker (og vi antager, at x = 14 dage):
række id prv navn dato 1 25 ... A 1 jan 2 25 ... A 3 jan 3 25 ... A 15 jan 4 25 ... A 19 jan 5 25 ... A 29 jan
Række 2 skal ikke bevares, det er tydeligt, men for alle rækkerne 3, 4, og 5 gælder, at "der er mere end x dage mellem at det samme 'navn' forekommer hos et 'id_nr'." Skal de derfor alle bevares?
Med din yderligere forklaring med bakterierne i #7 vil jeg gætte på, at kravet er dette: for hver id - navn kombination bevarer du den ældste række. For hver af disse bevarede rækker bevarer du den ældste række med samme id og navn som er mindst 14 dage yngre. Og for hver af de nye bevarede rækker bevarer du igen den ældste række med samme id og navn som er mindst 14 dage yngre o.s.v. Altså rækkerne 1, 3, og 5 skal bevares, men ikke 2 og 4.
Hvis det er korrekt forstået, så der vel en opskrift på en gentagen søgning, der starter med noget som SELECT * FROM minTabel ORDER BY dato GROUP BY id_nr, navn. Resultatet bevares i applikationen. Og så en løkke: FOR EACH [bevaret resultat] WHILE [der kommer nye resultater] SELECT * FROM minTabel WHERE [id_nr = id_nr i det sidste resultat AND navn = navn i det sidste resultat AND dato er mindst 14 dage større end dato for sidste resultat ORDER BY date GROUP BY id_nr, navn Gem det fundne resultat
Jeg havde slet ikke forsoegt at loese det i SQL, fordi jeg ikke tror at SQL er den rigtige maade at goere det paa. Det vil vaere nemmere og performe bedre at lave det i applikationen.
SELECT id_nr,prv_nr,navn,dato FROM dintabel t1 WHERE NOT EXISTS (SELECT * FROM dintabel t2 WHERE t2.id_nr = t1.id_nr AND t1.dato > t2.dato AND t2.dato >= DATE_SUB(t1.dato, INTERVAL x DAY))
#10 - lidt forsinket - din query giver, så vidt jeg kan se, alle rækker hvor datoen er for eksempel x+1 og x+2 dage efter den første forekomst. Det er mit gæt fra #7 (men desværre ikke afklaret af spørgeren,) at der skal være mindst x dage mellem forekomsterne for at de skal vises.
Ad 8#: Ok, kan godt se at jeg ikke har været præcis nok i min formulering. I dit eksempel skal kun række 1 bevares. Rationalet er, at hvis bakterien genfindes inden for 14 dage, så betragtes det som samme infektion, og er derfor ikke interessant. Jeg ønsker altså kun at bevare første fund af en bakterie på en given lokalitet, og hvis den dukker op mere end 14 dage (antallet af dage afhænger af hvilken bakterie vi snakker om) efter at den er set sidst.
Ad 10#: Jeg prøver det lige af. Det kan SAGTENS være, at det ikke er smart at lave sorteringen i SQL.
Smider I ikke et svar begge to, så deler jeg pointene?
Njah, kan ikke lige få det til at spille, men det betyder ikke at der er noget galt med din query. Sagen er den, at jeg henter data fra en Oracle db og ind i SAS, hvor jeg laver min databehandling. SAS kører en amputeret form for SQL. Den vil ikke kendes ved DATE_SUB. Jeg må lige greje hvordan jeg laver en mellemstation mellem databasen og SAS.
Nå, men tak for hjælpen (igen). Jeg skal nok finde ud af det herfra.
Nå, vi skrev lig forbi hinanden. Jeg skal nok give dig besked når jeg ved om det virker.
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.