Avatar billede ae03 Novice
31. januar 2012 - 13:40 Der er 8 kommentarer og
1 løsning

Udtræk af nyeste registrering for unikke personer

Jeg skal udtrække den nyeste registrering (DATO) af HØJDE og VÆGT for hver person (CPR).

Det går fint nok med nedenstående kode bortset fra, at der åbenbart er flere registreringer på samme dato for enkelte personer. Nedenstående udtræk rummer flere records, end hvis jeg med samme WHERE-forudsætninger udtrækker distinct CPR fra VAEKST-tabellen.

Hvordan får jeg den lige skruet sammen, så jeg i sidste ende kun har unikke CPR med i mit udtræk? Der er desværre ikke klokkeslet på registreringerne. Der er et felt OBNR, der så vidt jeg kan gennemskue rummer unikke registrerings-id, så det kan vel klares ved at vælge maks-værdien af denne, på samme måde som for datoen. Hvis det kan klares enklere end nedenstående, vil jeg meget gerne have en løsning på dette.

Da jeg ikke kan udelukke, at nogle dobbeltregistreringer skyldes en eller anden form for fejlregistrering (fx af HØJDE eller VÆGT), vil jeg gerne i første omgang lave et udtræk, hvor jeg ikke fjerner dobbeltregistreringerne men i stedet sorterer på count(CPR). Det kan jeg ikke få til, når jeg samtidig skal have HØJDE og VÆGT med i udtrækket.


Min sql-kode:
select CPR, HØJDE, VÆGT, DATO
from VAEKST
right join
    (
    select CPR as CPRt, max(DATO) as DATOt
    from VAEKST
    where substring(CPR,5,2)=94 and
        year(DATO)=2009 and month(DATO)>7
    group by CPR
    ) as t1
on VAEKST.CPR=t1.CPRt and
    VAEKST.DATO=t1.DATOt
order by CPR
31. januar 2012 - 14:55 #1
Din tabel vaekst synes at have, i det mindste, disse felter:

vækst
id cpr højde vægt dato

For hver cpr skal du have den nyeste registrering af højde og vægt.  Hvis der er mere end en registrering på en enkelt dato er den nyeste registrering den med det højeste id nummer.

Er det ikke hvad du får med denne enkle query

SELECT MAX(id) AS id, cpr, højde, vægt, dato FROM vaekst GROUP BY cpr;
Avatar billede ae03 Novice
31. januar 2012 - 15:04 #2
Umiddelbart har jeg ikke andet id på de enkelte poster end det omtalte OBNR. Så vidt jeg kan se på tabellen, er det unikt for hver registrering, men det er ikke fortløbende. De første 3-5 cifre rummer tilsyneladende en eller anden form for ident for den person, som har foretaget registreringen. Jeg kan derfor ikke umiddelbart blot basere det på værdien i OBNR. Den vil formentlig kunne bruges til at skelne mellem flere registreringer fra samme dag, men da der er registreringer fra flere år, kan der sagtens være flere personer, som har registreret for samme person.
Havde det bare været så simpelt.
31. januar 2012 - 16:14 #3
Du går i det oprindelige spørgsmål ud fra, at feltet OBNR rummer unikke registrerings-id, men i #2 synes du tvært imod at antage, at OBNR ikke er unikt, men at der kan være flere registreringer med det samme OBNR.  Det kunne du vel teste ved denne query:

SELECT OBNR, COUNT(OBNR) AS antal FROM VAEKST WHERE COUNT(OBNR) > 1

Hvis du ikke får noget resultat, så skulle OBNR være unikt.  Så hvis der for en cpr foretages flere registreringer på en dag, så vil disse i så fald have forskellige OBNR numre.  Spørgsmålet er så, om senere registreringer vil have større OBNR numre end tidligere registreringer.  Hvis det ikke nogen steder i tabellen fremgår hvilen registrering er den seneste hvis der er flere registreringer på en dag, så kan du heller ikke søge på det.  Eller er det mig der er tosset?  Hvor har du tabellen fra?  Hvordan bliver registreringerne foretaget?  Det må vel fremgå et eller andet sted fra hvad felterne indeholder, specielt hvordan OBNR feltet indføres eller dannes.
Avatar billede ae03 Novice
01. februar 2012 - 13:31 #4
Nej, jeg synes da, at jeg skriver, at OBNR formentlig er unikt. Men da OBNR ikke er en fortløbende nummerering, kan jeg ikke bare vælge max(OBNR).
Fordi de første cifre i OBNR angiver, hvilken medarbejder der har foretaget registreringen, vil max give mig den seneste registrering for den medarbejder, der har den højeste kode, ikke den nyeste registrering generelt.
En hurtig test viser, at der er et tilfælde, hvor samme OBNR forekommer to gange. Jeg vil tro, at det skyldes en fejl, idet den oprindelige database, som data stammer fra, fungerede ret dårligt. Den ene dobbeltregistrering er til at komme udenom, men som sagt afhjælper det ikke problemet, når højeste værdi af OBNR ikke er lig med nyeste registrering.
01. februar 2012 - 14:35 #5
Det er måske mig, der ikke har forstået problemstillingen.  Lad mig fortælle, hvad jeg forstår, så kan du rette mig, hvor det er nødvendigt.

Du har en bestående tabel, hvor der over en årerække er registreret vægt og højde for forskellige personer (cpr numre).  Du vil nu for hver person trække de data ud, der er registreret den seneste dato.  Hvis der for en person på den seneste dato er flere registrereinger vil du kun have en af registreringerne.  Du siger, at du kun vil have unikke cpr i dit udtræk.  Det i sig selv er let nok og kan gøres på flere måder.

Men du vil ikke have en tilfældig registrering, men den registrering der er foretaget senest på dagen.  Samtidig synes du at sige, at tabellen ikke indeholder oplysninger hvorved rækkefølgen af registreringerne kan bestemmes.  Hvor du i dit oprindelige spørgsmål siger, at "det kan vel klares ved at vælge maks-vprdien af denne" (OBNR) siger du i #2, at du kan "ikke umiddelbart blot basere det på værdien i OBNR." 

Så hvis det ikke ud fra tabellens indhold kan bestemmes i hvilken rækkefølge indenfor en enkel dato registreringerne blev foretaget, så kan du heller trække den seneste registrering ud.  Eller er det min logik der fejler mig eller har jeg forstået dig forkert?  Du må enten gætte eller vælge en tilfældig registrering.

Jeg forestiller mig data noget i retning af:

OBNR CPR dato højde vægt
ABCD172 2012-01-12 1304441913 176 76
ABCD173 2012-01-12 1304441913 177 78
EFGH541 2012-01-12 1304441913 172 74

Det er så vel et godt gæt, at ABCD173 er medarbejder ABCD's 173de registrering og derfor senere end ABCD172 som vel er ABCD's 172de registrering, men det kan ikke bestemmes, om EFGH541 er før eller efter ABCD173.

Er det således det hænger sammen?
Avatar billede ae03 Novice
01. februar 2012 - 15:55 #6
Beklager, hvis jeg ikke har fået forklaret mig tydeligt.

Jeg skal have data fra den seneste registreringsdato, men ikke nødvendigvis den seneste registrering fra den dag. Når der er flere registreringer fra samme dag, frygter jeg, at det kan skyldes fejl fra det personale, som har foretaget registreringerne. De er ikke alle lige kompetente i brug af pc.

Derfor kan der meget vel være registreringer, hvor højde eller vægt mangler, eller hvor fx højde er registreret som 1,78 frem for 178, og hvor der så er foretaget en ny registrering i stedet for en rettelse af den eksisterende. Derfor vil jeg gerne i første omgang have en liste sorteret efter count af personforekomster, så jeg kan se dobbeltregistreringerne igennem manuelt. Der er kun ca. 50 dobbeltregistreringer, så det er overkommeligt.

Derefter skal jeg bruge udtræk med unikke personer. Jeg har en formodning om, at OBNR kan bruges til at tidsbestemme, så længe registreringerne er foretaget af den samme medarbejder, men jeg er ikke sikker. Dem oprindelige databaseløsning fungerede ret dårligt, og dokumentation for datastruktur m.m. i relation til databaseopbygningen findes ikke. Leverandøren af den nu skrottede databaseløsning stoppede vedligeholdelsen, da der blev stillet krav om dokumantation og fejlretning. Så jeg ved kun det om OBNR, som jeg kan se i tabeludtræk. De første cifre er de samme for den samme medarbejder, og tilsyneladende stiger de sidste cifre med stigende dato. På grund af denne usikkerhed vil det være en fordel med en løsning, som ikke benytter OBNR.

I forhold til OBNR er det relevant, at det ikke umiddelbart er tydeligt, hvor mange af de ca. 10 cifre (p.t. har vi netværksproblemer, så jeg kan ikke komme til data), der er medarbejderangivelse, og hvor mange der tæller fortløbende. Det kan jeg sikkert finde ud af ved en grundig gennemgang af tabellen, men det vil kræve noget analysearbejde.

Håber, at det tydeliggjorde, hvad jeg mener.
01. februar 2012 - 17:07 #7
Nej, det er volapyk for mig.  Det er uden tvivl mig, der er for dum, så måske skulle vi stoppe her og nu.  Fortæller du, at med undtagelse af cirka 50 tilfælde er der på en enkel dato højst en registrering for hvert cpr nummer?  Og vil du have to forskellige queries?  I den første query udtrækker du de cirka 50 tilfælde, hvor et cpr er registreret mere end en gang på en dato.  Du vil så manuelt gennemgå de tilfælde og tilrette tabellen, således at hvis du har:

1304441913 2012-01-21 176
1304441913 2012-01-21 1.76
1304441913 2012-01-21 null 73

så skønner du at personen den dato var 1.76 meter høj og vejede 73 kg, og du sletter to rækker i tabellen og retter den tredje til 1.76 og 73

Og når der så tabellen er renset, så der ikke længere er cpr's der er registreret to gange på samme dato, så udtrækker du for hvert forekommende cpr højde og vægt for den seneste registreringdato?

I så fald kunne din første query være noget med

SELECT * FROM VAEKST WHERE CPR = (SELECT CPR FROM VAEKST WHERE COUNT(*) > 1 GROUP BY DATO)

Og når duplikaterne er renset ud, så må den seneste registrering for hver cpr være den for den højeste dato, og fordi der ikke længere er nogen duplikater vil cpr'erne være unikke.  Så burde dette virke:

SELECT CPR, HØJDE, VÆGT, MAX(DATO) FROM VAEKST GROUP BY CPR

Eller har jeg stadig ikke forstået noget af det på trods af dine tydelige forklaringer?
Avatar billede ae03 Novice
02. februar 2012 - 08:17 #8
Det er en ret god regel inden for kommunikation, at det ikke er modtageren, der er dum, men afsenderen, der ikke udtrykker sig klart nok. I øvrigt tyder din sidste kommentar nu på, at jeg er ved at have forklaringen på plads.

Når jeg foretager en kørsel med queryen fra min første kommentar, er der lidt flere resultater med, end når jeg kører denne:

select distinct CPR
from ebj20100104.VAEKST
where substring(CPR, 5,2)=94 and
    year(DATO)=2009 and month(DATO)>7

Det må, så vidt jeg kan se, være fordi, at der er nogle CPR, for hvilke der i den relevante tidsperiode fra august 2009 til udtrækket af mine data i 01 2010 er flere registreringer på samme DATO = max(DATO).

Du har nok ret i, at det enkleste er at trække det over i en midlertidig tabel, som jeg derefter renser ud i frem for at prøve at få det hele ind i en query.
02. februar 2012 - 08:51 #9
Jamen hvis det nærmer sig at falde på plads, så opretter jeg et svar.
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester