Toon posts:

[SQL/Oracle] laatste 5 gegevens

Pagina: 1
Acties:
  • 478 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een tabel met allerlei gegevens, laten we deze gewoon "gegevens" noemen.
Het bevat een soort historiek ter verduidelijking.

bvb:
gegevens.klant
gegevens.datum
gegevens.product
gegevens.aantal

Nu is het de bedoeling dat ik van alle klanten de laatste 5 verkochte producten krijg.

Ik kan niet werken met een ingegegeven datum, want voor klant X is de laatste v/d 5 verkopen misschien nogmaar van begin deze week, terwijl dat van klant Y misschien al van vorige jaar geleden is.

Wat ik zelf heb (maar wat niet werkt)

SQL:
1
2
3
4
5
6
7
8
9
10
SELECT x.klant, x.product, x.aantal
FROM gegevens x
WHERE x.datum IN (
 SELECT * FROM (
  SELECT DISTINCT y.datum 
  FROM gegevens y 
  WHERE y.klant = x.klant
  ORDER BY y.datum DESC)
 WHERE ROWNUM <= 5)
ORDER BY x.klant, x.product


Maar deze werkt niet want hij herkent x.klant niet op de volgende lijn in de subquery.
SQL:
1
WHERE y.klant = x.klant

Acties:
  • 0 Henk 'm!

  • Cyphax
  • Registratie: November 2000
  • Laatst online: 23:21

Cyphax

Moderator LNX
herkent ie daar ook niet gegevens.klant, ipv x.klant?

Saved by the buoyancy of citrus


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

DISTINCE?

Dat zal de fout wel niet zijn, maar wie weet. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nee ... gegevens.klant herkent hij niet...

en het moet idd DISTINCT zijn, maar dat is gewoon een typfout...

Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

je selecteert ook geen klant....

in
code:
1
2
3
4
SELECT DISTINCT y.datum 
  FROM gegevens y 
  WHERE y.klant = x.klant
  ORDER BY y.datum DESC



maar kijk ook eens naar de rank functie ()

http://www.adp-gmbh.ch/ora/sql/analytical/top_n.html

En volgens mij moet je in jouw geval geen disticnt gebruiken, want een klant kan op een dag ook 2 produkten kopen... toch?

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
waarom zit de extra SELECT FROM in de subquery in he WHERE?

SQL:
1
2
3
4
5
6
7
8
SELECT x.klant, x.product, x.aantal
FROM gegevens x
WHERE x.datum IN (
  SELECT DISTINCT y.datum 
  FROM gegevens y 
  WHERE y.klant = x.klant AND ROWNUM <= 5
  ORDER BY y.datum DESC)
ORDER BY x.klant, x.product


Bovenstaande zou ik verwachten, maar ik ken Oracle niet erg goed, dus misschien zit ik er wel naast.

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

P_de_B schreef op vrijdag 26 augustus 2005 @ 13:50:
waarom zit de extra SELECT FROM in de subquery in he WHERE?

SQL:
1
2
3
4
5
6
7
8
SELECT x.klant, x.product, x.aantal
FROM gegevens x
WHERE x.datum IN (
  SELECT DISTINCT y.datum 
  FROM gegevens y 
  WHERE y.klant = x.klant AND ROWNUM <= 5
  ORDER BY y.datum DESC)
ORDER BY x.klant, x.product


Bovenstaande zou ik verwachten, maar ik ken Oracle niet erg goed, dus misschien zit ik er wel naast.
werkt soms (dus helemaal niet) omdat EERST de rownum < 5 wordt geevalueerd en dan pas gesorteerd.

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
leuk_he schreef op vrijdag 26 augustus 2005 @ 13:48:
je selecteert ook geen klant....

in
code:
1
2
3
4
SELECT DISTINCT y.datum 
  FROM gegevens y 
  WHERE y.klant = x.klant
  ORDER BY y.datum DESC



maar kijk ook eens naar de rank functie ()

http://www.adp-gmbh.ch/ora/sql/analytical/top_n.html

En volgens mij moet je in jouw geval geen disticnt gebruiken, want een klant kan op een dag ook 2 produkten kopen... toch?
Nee, die x.klant moet verwijzen naar de hoofdquery (wat eigenlijk twee niveau's hoger is, wat wschl het probleem geeft). En de code is niet exact aan mijn situatie, maar ik heb het eenvoudig voorgeteld. De database in het duits met foute namen en foute links en dus niet te begrijpen. Maar dit voorbeeldje omschrijft wel héél correct mijn probleem. Maar ik moet wel degelijk DISTINCT doen, want als er op de 5 laatste dagen 8 verkopen waren, dan moet ik ze alle 8 hebben.

Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

code:
1
2
3
4
5
6
7
8
9
10
SELECT x.klant, x.product, x.aantal 
FROM gegevens x 
WHERE x.datum IN ( 
 SELECT v.datum FROM ( 
  SELECT y.klant, y.datum  
  FROM gegevens y  
  ORDER BY y.datum DESC) v
 WHERE v.klant = x.klant 
 AND ROWNUM <= 5) 
ORDER BY x.klant, x.product

Who is John Galt?


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
P_de_B schreef op vrijdag 26 augustus 2005 @ 13:50:
waarom zit de extra SELECT FROM in de subquery in he WHERE?

SQL:
1
2
3
4
5
6
7
8
SELECT x.klant, x.product, x.aantal
FROM gegevens x
WHERE x.datum IN (
  SELECT DISTINCT y.datum 
  FROM gegevens y 
  WHERE y.klant = x.klant AND ROWNUM <= 5
  ORDER BY y.datum DESC)
ORDER BY x.klant, x.product


Bovenstaande zou ik verwachten, maar ik ken Oracle niet erg goed, dus misschien zit ik er wel naast.
Omdat hij in jouw geval eerst de 5 eerste rijen neemt en ze dan pas sorteert, dus dan heb ik niet de laatste datums.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
justmental schreef op vrijdag 26 augustus 2005 @ 13:56:
code:
1
2
3
4
5
6
7
8
9
10
SELECT x.klant, x.product, x.aantal 
FROM gegevens x 
WHERE x.datum IN ( 
 SELECT v.datum FROM ( 
  SELECT y.klant, y.datum  
  FROM gegevens y  
  ORDER BY y.datum DESC) v
 WHERE v.klant = x.klant 
 AND ROWNUM <= 5) 
ORDER BY x.klant, x.product
Dit zou het wel eens kunnen zijn, ik zat op iets gelijks te zoeken, maar kwam telkens weer in de knoei ... even kijken.

Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Verwijderd schreef op vrijdag 26 augustus 2005 @ 13:56:
[...]


Omdat hij in jouw geval eerst de 5 eerste rijen neemt en ze dan pas sorteert, dus dan heb ik niet de laatste datums.
Meen je dat? 8)7

Weer wat geleerd :)

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

code:
1
2
3
4
5
6
7
8
9
10
11
SELECT  x.klant, x.product, x.aantal 
   FROM
   (SELECT x.klant, x.product, x.aantal , x.datum ,
        RANK() OVER
            (PARTITION BY x.klant
            ORDER BY x.klant,x.datum  
             DESC NULLS LAST) AS r
      FROM gegevens x 
      ORDER BY x.klant,x.datum NULLS LAST)
     )
   WHERE r <6



(als je een beetje recent oracle hebt)

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ça marche ! je vous remercié tous !

Nog even tonen aan welk f*cked-up SQL-statement
jullie meegeholpen hebben ...

(deze foute code is grotendeels de schuld van de
database die niet echt relationeel opgesteld is)

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT ASDPLATZ.PLATZ, ASDPLATZ.NAME1, ASDPLATZ.ORT, ASDSORTE.MDEBEZ, AIDPLASO.BUDAT, AIDPLASO.ENT
FROM ASDPLATZ, ASDSORTE, AIDPLASO, BSDTOUR1
WHERE AIDPLASO.PLATZ = ASDPLATZ.PLATZ
AND BSDTOUR1.PKNR = ASDPLATZ.PLATZ
AND (ASDSORTE.SORTE = AIDPLASO.SORTE AND ASDSORTE.SORIND = AIDPLASO.SORIND)
AND BSDTOUR1.TOUR = &route
AND BSDTOUR1.TAG = &dag
AND AIDPLASO.BUDAT IN 
(SELECT z.BUDAT FROM 
 (SELECT DISTINCT AIDPLASO.PLATZ, AIDPLASO.BUDAT 
  FROM AIDPLASO 
  ORDER BY AIDPLASO.PLATZ, AIDPLASO.BUDAT DESC) z
 WHERE z.platz = asdplatz.platz
 AND ROWNUM <= 5)
ORDER BY ASDPLATZ.PLATZ, AIDPLASO.BUDAT

Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 22:32

The Eagle

I wear my sunglasses at night

Ach, als je een leuk Oracle-statement wilt hebben, dan heb ik er ook nog wel 1 voor je:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
SELECT I.VENDOR_SETID, I.VENDOR_ID, I.VNDR_LOC, I.SBI_NUM, TO_CHAR(I.CREATE_DATE,'YYYY-MM-DD'), C.NAME1, D.ADDRESS1, D.ADDRESS2, D.ADDRESS3, D.ADDRESS4, D.CITY, D.STATE, D.POSTAL, D.COUNTRY, D.NUM1, D.NUM2, D.COUNTY, D.HOUSE_TYPE, J.SBI_HOLD_FLG, A.BUSINESS_UNIT, A.VOUCHER_ID, TO_CHAR(A.INVOICE_DT,'YYYY-MM-DD'), A.INVOICE_ID, F.INV_ITEM_ID, F.QTY_VCHR, F.UNIT_OF_MEASURE, K.MERCHANDISE_AMT, A.TXN_CURRENCY_CD, K.VAT_INV_AMT, K.VAT_NONINV_AMT, K.SALETX_AMT, K.USETAX_AMT
  FROM PS_VOUCHER A, PS_VENDOR C, PS_VENDOR_ADDR D, PS_VOUCHER_LINE F, PS_VENDOR_LOC B, PS_VCHR_SBI_P I, PS_VCHR_SBI_DATA_P J, PS_SBI_VCHR_AMOUNT K, PS_RUN_CNTL_AP E
  WHERE I.OPRID = 'VOGELS'
    AND J.OPRID = 'VOGELS'
    AND E.OPRID = 'VOGELS'
    AND ( J.VENDOR_SETID = B.SETID
     AND J.VENDOR_ID = B.VENDOR_ID
     AND J.VNDR_LOC = B.VNDR_LOC
     AND B.VENDOR_ID = C.VENDOR_ID
     AND B.EFFDT =
        (SELECT MAX(B_ED.EFFDT) FROM PS_VENDOR_LOC B_ED
        WHERE B.SETID = B_ED.SETID
          AND B.VENDOR_ID = B_ED.VENDOR_ID
          AND B.VNDR_LOC = B_ED.VNDR_LOC
          AND B_ED.EFFDT <= SYSDATE)
     AND B.SETID = C.SETID
     AND C.SETID = D.SETID
     AND C.VENDOR_ID = D.VENDOR_ID
     AND B.PRIM_ADDR_SEQ_NUM = D.ADDRESS_SEQ_NUM
     AND D.EFFDT =
        (SELECT MAX(D_ED.EFFDT) FROM PS_VENDOR_ADDR D_ED
        WHERE D.SETID = D_ED.SETID
          AND D.VENDOR_ID = D_ED.VENDOR_ID
          AND D.ADDRESS_SEQ_NUM = D_ED.ADDRESS_SEQ_NUM
          AND D_ED.EFFDT <= SYSDATE)
     AND A.BUSINESS_UNIT = J.BUSINESS_UNIT
     AND A.VOUCHER_ID = J.VOUCHER_ID
     AND A.BUSINESS_UNIT = F.BUSINESS_UNIT
     AND A.VOUCHER_ID = F.VOUCHER_ID
     AND F.BUSINESS_UNIT = K.BUSINESS_UNIT
     AND F.VOUCHER_ID = K.VOUCHER_ID
     AND F.VOUCHER_LINE_NUM = K.VOUCHER_LINE_NUM
     AND I.OPRID = :1
     AND I.RUN_CNTL_ID = :2
     AND I.OPRID = J.OPRID
     AND I.RUN_CNTL_ID = J.RUN_CNTL_ID
     AND I.VENDOR_SETID = J.VENDOR_SETID
     AND I.VENDOR_ID = J.VENDOR_ID
     AND I.VNDR_LOC = J.VNDR_LOC
     AND I.SBI_NUM = J.SBI_NUM
     AND I.PROCESS_INSTANCE = J.PROCESS_INSTANCE
     AND J.OPRID = E.OPRID
     AND J.RUN_CNTL_ID = E.RUN_CNTL_ID
     AND (( E.VENDOR_SELECT_OPTN = 'A')
     OR ( E.VENDOR_SELECT_OPTN = 'S'
     AND E.SETID = J.VENDOR_SETID
     AND E.VENDOR_ID = J.VENDOR_ID)) )
  ORDER BY 1, 2, 3, 4, 5


There :Y)
Ingangsdatums zijn erg leuk, maar het levert wel veel (inner) joins op zichzelf op ;) En dan is dit nog een kleintje....

Met dank aan PeopleSoft FSCM 8.0

[ Voor 80% gewijzigd door The Eagle op 26-08-2005 15:32 ]

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)

Pagina: 1