Avatar billede torbenuk Novice
04. juli 2011 - 08:48 Der er 6 kommentarer og
1 løsning

Forespørgsel sidste 30

Jeg har en stor tabel med med ca. 1000 forskellige aktiers dagskurser for ca. 5 år. Aktierne er sorteret efter navn og herefter dato, således at den seneste dato er sidst.

Jeg har brug for en forespørgsel, der kan give mig de sidste 60 dagskurser for hver enkelt aktie. Dvs. en ny tabel med 60.000 dagskurser (1000 aktier * 60 dagskurser).

Måden som min tabel er sorteret på betyder, at det altid er de nederst 60 dagskurser, som jeg har brug for. Tabellen ser således ud:

Aktie A  15.05.09        101,50
Aktie A  16.05.09        102,50
.
.
Aktie A 03.07.11        110,25
Aktie B 15.05.09        111,25
.
.
Aktie B 03.07.11        116,25

Håber at nogen kan hjælpe.
Avatar billede finb Ekspert
04. juli 2011 - 09:16 #1
følger tråden ... mvh finb
Avatar billede Slettet bruger
04. juli 2011 - 21:44 #2
SELECT [aNavn], [tidsp], [kurs] FROM
  (SELECT TOP 60000 [aNavn], [tidsp], [kurs]
    FROM Akurser ORDER BY [tidsp] DESC)
ORDER BY tidsp, aNavn
Avatar billede Slettet bruger
04. juli 2011 - 21:56 #3
korrektion ...

SELECT [aNavn], [tidsp], [kurs] FROM
  (SELECT TOP 60000 [aNavn], [tidsp], [kurs]
    FROM Akurser ORDER BY [tidsp] DESC)
ORDER BY aNavn,tidsp


og endeligt gennemsnitkurser:

SELECT [aNavn], avg([kurs]) FROM
  (SELECT TOP 60000 [aNavn], [tidsp], [kurs]
    FROM Akurser ORDER BY [tidsp] DESC)
GROUP BY aNavn;
Avatar billede torbenuk Novice
05. juli 2011 - 09:43 #4
Tak for dit svar brugerekspert. Jeg vil teste i løbet af de næste par dage. Men jeg ser et lille problem i den foreslåede løsning, nemlig det faktum, at Aktie A's sidst kurs kan være den 03.07.11 mens aktie B's sidste kurs kan være den 26.06.11. Derfor vil din løsningen nok virke i teorien, men i praksis er løsningen for simpel.

Jeg har også fået en anden løsningen (se nedenfor), som jeg også vil teste. Nu er jeg ikke lige ekspert på dette område, men løsningen synes at gøre, hvad jeg har brug for.

Men som sagt går der desværre lige nok et par dage inden jeg kan teste. Jeg vender tilbage. men foreløbigt mange tak for dit svar.

Anden løsning:

TOP n records per group

You want the three most recent orders for each client. Use a subquery to select the 3 top orders per client, and use it to limit which orders are selected in the main query:
SELECT Orders.CustomerID, Orders.OrderDate, Orders.OrderID
FROM Orders
WHERE Orders.OrderID IN
  (SELECT TOP 3 OrderID                           
  FROM Orders AS Dupe                             
  WHERE Dupe.CustomerID = Orders.CustomerID       
  ORDER BY Dupe.OrderDate DESC, Dupe.OrderID DESC)
ORDER BY Orders.CustomerID, Orders.OrderDate, Orders.OrderID;
Points to note:

Since we have two copies of the same table, we need the alias.
Like EXISTS in the first example above, there is no problem with the subquery returning multiple records. The main query does not have to show any value from the subquery.
Adding the primary key field to the ORDER BY clause differentiates between tied values.
Avatar billede torbenuk Novice
08. juli 2011 - 10:24 #5
Jeg lukker denne her. Mit problem var, at min database var blevet  meget langsom, hvorfor jeg forsøgte at finde en forespørgsel der kunne reducere mine tabeller. Jeg har ikke valgte at anvende nogen løsninger i denne tråd, men jeg har i stedet gået alle tabeller og forespørgselser igennem, hvorved jeg har fået reduceret opdateringstiden væsentligt. Men min database er stadig langsom, men det kan jeg acceptere p.t. Takker for dit svar brugerekspert, idet jeg kan bruge svaret til en senere forespørgsel.
Avatar billede Slettet bruger
08. juli 2011 - 18:02 #6
Du har ret i at løsningen jeg skitserede kun 'virker' under 'visse forudsætninger' - jeg var faktisk godt klar over det allerede da postede svaret - iøvrigt rart at du som spørger ikke bare godtager hvad som helst ;)

Med inspiration fra 'anden løsning' i #4, er min umiddelbare konklussion at det ikke kan lade sig gøre medmindre hver post er unik. Det er hver post jo klart også hvis man anvender en samlet nøgle af aktienavn og tidspunkt til 'IN selection' i den indre select top

SELECT aNavn, tidsp, kurs
  FROM Akurser WHERE anavn & tidsp in
    (select top 30  anavn & tidsp from akurser as dupe
      where aKurser.aNavn=dupe.aNavn
      ORDER BY [tidsp] DESC,aNavn)
  ORDER BY aNavn, tidsp;

Hvis hver posts unikhed er angivet af et id, er det både enklere og kører sikkert hurtigere


SELECT aNavn,tidsp,kurs
  FROM Akurser WHERE id in
    (select top 30  id from akurser as dupe
      where aKurser.aNavn=dupe.aNavn
      ORDER BY [tidsp] DESC,aNavn)
  order by aNavn, tidsp
Avatar billede torbenuk Novice
08. juli 2011 - 19:56 #7
Hej brugerekspert,

I min database er hver post unik, idet jeg anvender en kombination af navn og tidspunkt (som du også skriver). Jeg vil helt sikker teste dit forslag, for jeg har stadig brug for at reducere min opdateringstid. Min database kører en stor forespørgsel, som danner en ny tabel. Der bliver foretaget rigtige mange beregninger vha. diverse vba-moduler. Nu er jeg jo rent amatør på dette område, så noget af min programmering er sikkert ikke den mest optimale. Det tager derfor 3 timer at opdatere ca. 1.000 objekter. Hvis jeg kunne få det ned på 1 time vil jeg være glad. Måske jeg skulle åbne en ny tråd herom. Men takker igen for 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
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