Avatar billede d9ha2 Nybegynder
01. oktober 2010 - 11:48 Der er 10 kommentarer og
1 løsning

hente record fra relateret tabel med seneste dato

Var lidt hurtig til at lukke mit ? igår om Seneste dato fra relateret tabel. Jeg skal bruge flere oplysninger fra den record med den højeste dato, og løsningen vi kom frem til giver kun Højeste dato fra tabellen + data fra den record der er først i tabellen.

Jeg har prøvet at hente data ved at sætte en select med left join på t_Godkend på de værdier jeg skal bruge fra t_godkend, men får en pop up med at der ingen værdier er i tabellen. Ved ikke lige hvordan jeg kommer videre. SQL:

SELECT t_Udstyr.Identitet, t_Udstyr.Navn, t_Status.Status, t_Lokation.LokNavn, t_Lokation.LokID, DateAdd("d",t_Godkend!GodkLobeTid,SenesteDato) AS Udlob, t_Godkend.Godkender, t_Udstyr.Ejer, (Select Max(G1.GodkDato)  from t_Godkend AS G1 Where G1.Udstyr=t_Udstyr.Identitet) AS SenesteDato

FROM t_Status INNER JOIN
              (t_Lokation INNER JOIN
                          (t_Godkend INNER JOIN t_Udstyr ON  t_Godkend.GodkendID=t_Udstyr.Godk)
              ON t_Lokation.LokID=t_Udstyr.Lokation)
ON t_Status.StatusID=t_Udstyr.StatusNr

ORDER BY DateAdd("d",t_Godkend!GodkLobeTid,t_Godkend!GodkDato);


Det giver fint den seneste dato og det rigtige udløb, men Godkender er forkert.
Avatar billede anlu Nybegynder
02. oktober 2010 - 20:06 #1
Lav fx en query q_SenesteGodkPrUdstyr med en SQL a la denne

SELECT  g.GodkendID, g.Udstyr, g.GodkDato, g.Godkender
FROM t_Godkend g
INNER JOIN
(SELECT Udstyr, max(GodkDato) AS MaxDato FROM t_Godkend GROUP BY Udstyr) AS g_seneste
ON g.Udstyr = g_seneste.Udstyr AND g.GodkDato = g_seneste.MaxDato

(hvor du kan tilføje flere felter med g.Felt1, g.Felt2 i select listen)

Denne query (som jo altså giver dig den seneste godkendelse inkl. data pr. Udstyr)  kan du så bruge som "tabel" i din hovedquery. Du kan nok også få flettet princippet med en selvjoin direkte ind i din hovedquery, men spørgsmålet er om det ikke er mere overskueligt at holde den i en selvstændig query.
Avatar billede d9ha2 Nybegynder
04. oktober 2010 - 15:23 #2
Hej Anlu, tak for input. Ser egentlig ud til at virke, men når jeg gemmer forespørgslen og så åbner den efterfølgende er Access 2003 gået i selvsving og har tilføjet kantede paranteser og semikolon inde i sql-sætningen, hvofor den selvfølgelig ikke virker mere.

"FROM t_Godkend AS g INNER JOIN [SELECT Udstyr, max(GodkDato) AS MaxDato FROM t_Godkend GROUP BY Udstyr; ] AS g_seneste ON (g.Udstyr=g_seneste.Udstyr) AND (g.GodkDato=g_seneste.MaxDato);"

Hvad gør man lige ved det?
Avatar billede anlu Nybegynder
04. oktober 2010 - 19:36 #3
Hmm, interessant... eller mærkeligt...?! - jeg har lige prøvet at gemme eksemplet i 2003 (med SP2). Den laver SQL'en om således:

SELECT g.GodkendID, g.Udstyr, g.GodkDato, g.Godkender
FROM t_Godkend AS g INNER JOIN [SELECT Udstyr, max(GodkDato) AS MaxDato FROM t_Godkend GROUP BY Udstyr]. AS g_seneste ON (g.GodkDato = g_seneste.MaxDato) AND (g.Udstyr = g_seneste.Udstyr);

og det virker stadig. Jeg undrede mig lidt over punktummet efter den kantede slutparentes og prøvede at fjerne det, men det ville den ikke acceptere. Prøv evt. om denne version af sql'en virker for dig?
Avatar billede d9ha2 Nybegynder
05. oktober 2010 - 07:50 #4
Access laver desværre også denne om på samme måde, så den virker ikke. Kan se at jeg har servicepack 3
Avatar billede anlu Nybegynder
05. oktober 2010 - 17:09 #5
Den her slags mærkeligheder kan gøre mig noget så træt...
Hjælper det evt. at "vende" join-rækkefølgen???

SELECT  g.GodkendID, g.Udstyr, g.GodkDato, g.Godkender
FROM
(SELECT Udstyr, max(GodkDato) AS MaxDato FROM t_Godkend GROUP BY Udstyr) AS g_seneste
INNER JOIN
t_Godkend AS g
ON g.Udstyr = g_seneste.Udstyr AND g.GodkDato = g_seneste.MaxDato
Avatar billede d9ha2 Nybegynder
06. oktober 2010 - 08:16 #6
Samme problem

SELECT g.GodkendID, g.Udstyr, g.GodkDato, g.Godkender
FROM [SELECT Udstyr, max(GodkDato) AS MaxDato FROM t_Godkend GROUP BY Udstyr; ] AS g_seneste INNER JOIN t_Godkend AS g ON (g.Udstyr=g_seneste.Udstyr) AND (g.GodkDato=g_seneste.MaxDato);
Avatar billede d9ha2 Nybegynder
07. oktober 2010 - 14:37 #7
Har rodet lidt med det i mellemtiden og har prøvet at lave 2 forespørgsler, som jeg så samler i en 3. forespørgsel.

De 2 forespørgsler virker fint, men jeg har lidt problemer når jeg kæder dem sammen.

3. forespørgsel finder alle data på første record, men på efterfølgende records kommer kun værdier fra 1. forespørgsel og et beregnet felt med i resten er der null værdier.

Nogen der kan forklare, hvorfor der kommer null værdier i de efterfølgende records?


Forespørgsel 1 finder seneste godkendelsesdato for hvert stykke udstyr:
SELECT g_senest.Udstyr, Max(g_senest.GodkDato) AS MaxDato
FROM t_Godkend AS g_senest
GROUP BY g_senest.Udstyr ;

Forespørgsel 2 finder data fra tabellerne t_Udtsyr, t_status og t_lokation for hvert stykke udstyr:
SELECT t_Udstyr.Identitet, t_Udstyr.Navn, t_Udstyr.Godk, t_Udstyr.Ejer, t_Status.Status, t_Lokation.LokNavn
FROM t_Status INNER JOIN (t_Lokation INNER JOIN t_Udstyr ON t_Lokation.LokID = t_Udstyr.Lokation) ON t_Status.StatusID = t_Udstyr.StatusNr
WHERE (((t_Udstyr.Godk) Is Not Null));

3. forespørgsel samler de 2 første og joiner med t_godkend, hvorfra jeg skal bruge løbetid til at beregne tidspunkt for næste godkendelse sammen med maxdato, samt navn på godkender:

SELECT f_Godkend1.MaxDato, t_Godkend.Godkender, f_Godkend2.Identitet, f_Godkend2.Ejer, f_Godkend2.Status, f_Godkend2.Navn, f_Godkend2.LokNavn, DateAdd("d",[t_Godkend.GodkLobetid],f_Godkend1.MaxDato) AS Udlob
FROM (f_Godkend1 INNER JOIN t_Godkend ON (f_Godkend1.Udstyr = t_Godkend.Udstyr) AND (f_Godkend1.MaxDato = t_Godkend.GodkDato)) LEFT JOIN f_Godkend2 ON f_Godkend1.Udstyr = f_Godkend2.Identitet;
Avatar billede d9ha2 Nybegynder
08. oktober 2010 - 10:27 #8
Jeg har rodet lidt videre med det. og har lavet 2 forespørgsler som jeg joiner med t_Godkend tabellen i en 3. forespørgsel.

De 2 forespørgsler fungerer fint hver for sig, med det går lidt galt i 3. forespørgsel, da den finder værdier for 1 record som den skal, men i efterfølgende records tager den kun data med fra 1. forspørgsel og indsætter null værdier i resten af felterne.

Jeg er ikke med på hvorfor der kommer null værdier i de efterfølgende records.

1. forespørgsel finder maxdato i t_Godkend for hvert stykke udstyr:
SELECT g_senest.Udstyr, Max(g_senest.GodkDato) AS MaxDato
FROM t_Godkend AS g_senest
GROUP BY g_senest.Udstyr;


2. forespørgsel finder data fra t_Udstyr, t_Lokation og t_Status for hvert stykke udstyr:
SELECT t_Udstyr.Identitet, t_Udstyr.Navn, t_Udstyr.Godk, t_Udstyr.Ejer, t_Status.Status, t_Lokation.LokNavn
FROM t_Status INNER JOIN (t_Lokation INNER JOIN t_Udstyr ON t_Lokation.LokID = t_Udstyr.Lokation) ON t_Status.StatusID = t_Udstyr.StatusNr
WHERE (((t_Udstyr.Godk) Is Not Null));


3. forespørgsel skulle så finde data på hvert stykke udstyr og vise data fra t_godkend for den seneste godkendelsesdato på udstyret:
SELECT f_Godkend1.MaxDato, t_Godkend.Godkender, f_Godkend2.Identitet, f_Godkend2.Ejer, f_Godkend2.Status, f_Godkend2.Navn, f_Godkend2.LokNavn, DateAdd("d",[t_Godkend.GodkLobetid],f_Godkend1.MaxDato) AS Udlob
FROM (f_Godkend1 INNER JOIN t_Godkend ON (f_Godkend1.MaxDato = t_Godkend.GodkDato) AND (f_Godkend1.Udstyr = t_Godkend.Udstyr)) LEFT JOIN f_Godkend2 ON f_Godkend1.Udstyr = f_Godkend2.Identitet;
Avatar billede anlu Nybegynder
08. oktober 2010 - 20:33 #9
Hvad er betydningen af feltet Godk i t_Udstyr-tabellen? Jeg tænker på om du skulle undlade at begrænse f_Godkend2 på dette felt?

Ellers vil jeg tro at du burde lave en RIGHT JOIN i stedet for en LEFT JOIN, men det vil Access ikke, så for at komme uden om, kan du lave endnu en mellem-forespørgsel:

f_Godkend3:
SELECT f_Godkend1.Udstyr, f_Godkend1.MaxDato, t_Godkend.Godkender, t_Godkend.GodkLobetid
FROM f_Godkend1 INNER JOIN t_Godkend ON (f_Godkend1.MaxDato = t_Godkend.GodkDato) AND (f_Godkend1.Udstyr = t_Godkend.Udstyr);

og så bruge den i den endelige forespørgsel:
SELECT f_Godkend3.MaxDato, f_Godkend3.Godkender, f_Godkend2.Identitet, f_Godkend2.Ejer, f_Godkend2.Status, f_Godkend2.Navn, f_Godkend2.LokNavn, DateAdd("d",[f_Godkend3.GodkLobetid],f_Godkend3.MaxDato) AS Udlob
FROM f_Godkend3 RIGHT JOIN f_Godkend2 ON f_Godkend3.Udstyr = f_Godkend2.Identitet;

Giver det hvad du ønsker??
Avatar billede d9ha2 Nybegynder
11. oktober 2010 - 15:53 #10
Du har helt ret anlu, der er en fejl i opbygningen af tabellerne, Godk hører ikke hjemme i t_Udstyr.

Din Godkend 3 giver  alle records fra feltet godkender, så den holder ikke helt. Men når jeg ikke begrænser på Godk i t_Udstyr, kan jeg få det hele recorden med maxID ud i f_Godkend1 og så samle den med data fra de øvrige tabeller hentet ud i f_Godkend2

f_Godkend1:
SELECT t_Godkend.Udstyr, t_Godkend.GodkendID, t_Godkend.GodkDato, t_Godkend.Godkender, t_Godkend.GodkLobetid
FROM t_Godkend
WHERE t_Godkend.GodkDato = (Select max(g.GodkDato) FROM t_Godkend as g WHERE g.Udstyr = t_Godkend.Udstyr);


f_Godkend2:
SELECT t_Udstyr.Identitet, t_Udstyr.Navn, t_Udstyr.Godk, t_Udstyr.Ejer, t_Status.Status, t_Lokation.LokNavn
FROM t_Status INNER JOIN (t_Lokation INNER JOIN t_Udstyr ON t_Lokation.LokID = t_Udstyr.Lokation) ON t_Status.StatusID = t_Udstyr.StatusNr
WHERE (((t_Udstyr.Godk) Is Not Null));


Og til sidst en samleforespørgsel:
SELECT f_Godkend2.Identitet, f_Godkend2.Ejer, f_Godkend2.Status, f_Godkend2.Navn, f_Godkend2.LokNavn, DateAdd("d",[F_Godkend1.GodkLobetid],F_Godkend1.GodkDato) AS Udlob, F_Godkend1.Godkender
FROM F_Godkend1 INNER JOIN f_Godkend2 ON F_Godkend1.Udstyr = f_Godkend2.Identitet;


Du skal have mange tak for hjælpen, og jeg skal fluks aflevere point, hvis du lægger et svar.

mvh
Henrik
Avatar billede anlu Nybegynder
11. oktober 2010 - 16:03 #11
Pyh... det var en længere omgang, men godt at du tilsidst fik løst det :o)
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
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

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