[sql] Laagste waarde selecteren

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

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 18:03
Goeiedag,

Volgens mij is het antwoord vrij simpel, maar het is me even ontschoten!

Ik heb drie tabellen. Een tabel met een betaling, een tabel met een betalingsstatusgeschiedenis (hiervan kunnen meerdere record per betaling zijn) en een tabel met de verschillende statussen die mogelijk zijn. Nou wil ik graag alle betalingen en daarbij de meest recente betalingsstatus ophalen in één query. Zou zit ik te pielen met de GROUP BY en de aggregratie functies, maar volgens mij heb ik het toch verkeerd.

Dit heb ik nu, maar dat returnt alle rijen in de betalingsstatusgeschiedenis. Dat moet dus niet :P.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT
    p.Id, 
    p.MemberId, 
    p.BankAccountNumber, 
    p.Amount, 
    p.NotReceiveBefore, 
    m.FirstName, 
    m.BetweenName, 
    m.LastName, 
    ph.PaymentStatusDate, 
    ps.Name
FROM
    Payment AS p, 
    Member AS m, 
    PaymentHistory AS ph, 
    PaymentStatus AS ps
WHERE
    m.Id = p.MemberId AND
    ph.PaymentId = p.Id AND
    ps.Id = ph.PaymentStatusId
ORDER BY
    ph.PaymentStatusDate DESC

Kan iemand mij een zetje in de goede richting geven?

  • MrNGm
  • Registratie: Augustus 2004
  • Laatst online: 05-11 16:22
Je bent ps.Id, m.Id, ph.PaymentId, ph.PaymentStatusId vergeten in het SELECT gedeelte. Afaik moet dat er ook bij staan, als je iets in de WHERE clause wilt gebruiken.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT
    p.Id, p.MemberId, p.BankAccountNumber, p.Amount, p.NotReceiveBefore, 
    m.Id, m.FirstName, m.BetweenName, m.LastName, 
    ph.PaymentStatusDate, ph.PaymentStatusId, ph.PaymentId,
    ps.Name, ps.Id
FROM
    Payment AS p, 
    Member AS m, 
    PaymentHistory AS ph, 
    PaymentStatus AS ps
WHERE
    m.Id = p.MemberId AND
    ph.PaymentId = p.Id AND
    ps.Id = ph.PaymentStatusId
ORDER BY
    ph.PaymentStatusDate DESC


Zoiets?

  • Tukk
  • Registratie: Januari 2002
  • Laatst online: 11:27

Tukk

De α-man met het ẞ-brein

Ik neem aan dat er in de table PaymentHistory een datum veld zit (paymentstatusdate?), als je in een sbquery daar de meest recente record ophaalt dan ben je der toch?

iets als:
SQL:
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
SELECT
    p.Id, 
    p.MemberId, 
    p.BankAccountNumber, 
    p.Amount, 
    p.NotReceiveBefore, 
    m.FirstName, 
    m.BetweenName, 
    m.LastName, 
    ph.PaymentStatusDate, 
    ps.Name
FROM
    Payment AS p, 
    Member AS m, 
    
    PaymentStatus AS ps
WHERE
    m.Id = p.MemberId AND
    ph.PaymentId = p.Id AND
    ps.Id = (Select ph.PaymentStatusId 
                   from PaymentHistory AS ph 
                 where rowcount =1 
                   order by ph.paymentstatusdate)
ORDER BY
    ph.PaymentStatusDate DESC

[ Voor 4% gewijzigd door Tukk op 24-12-2006 11:50 ]

Q: How many geeks does it take to ruin a joke? A: You mean nerd, not geek. And not joke, but riddle. Proceed.


  • analog_
  • Registratie: Januari 2004
  • Niet online
code:
1
2
3
4
5
6
SELECT max(ph.PaymentStatusDate),ps.Name 
FROM Payment p
INNER JOIN PaymentHistory ph ON ph.PaymentId = p.Id
INNER JOIN PaymentStatus ps ON ps.ID = ph.PaymentStatusId
INNER JOIN Member m ON p.MemberId = m.Id
GROUP BY p.Id

Zou het zoiets kunnen zijn ?

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 18:03
MrNGm schreef op zondag 24 december 2006 @ 11:48:
Je bent ps.Id, m.Id, ph.PaymentId, ph.PaymentStatusId vergeten in het SELECT gedeelte. Afaik moet dat er ook bij staan, als je iets in de WHERE clause wilt gebruiken.

[...]

Zoiets?
Nee, dat is niet nodig :).
Tukk schreef op zondag 24 december 2006 @ 11:49:
Ik neem aan dat er in de table PaymentHistory een datum veld zit (paymentstatusdate?), als je in een sbquery daar de meest recente record ophaalt dan ben je der toch?
Dat klopt! Dat is inderdaad het veld dat je noemt.
iets als:
SQL:
1
...
Het probleem is dat die query niet matcht met de name. Dat is erg rot aan deze query, omdat je niet kunt groeperen op het ps.name veld (die kan immers best meerdere keren hetzelfde zijn).
Mr.SiS schreef op zondag 24 december 2006 @ 11:49:

[...]

Zou het zoiets kunnen zijn ?
Die haalt alleen de verschillende statussen op, maar niet de betalingen, die ik toch wel graag wil hebben :). Als ik het veld p.Id vervolgens toch toevoeg krijg ik alsnog drie rijen terug, terwijl het er juist één moet zijn :).

Iedereen alvast bedankt voor de hulp.

  • MacWebber
  • Registratie: September 2000
  • Niet online
Er vanuitgaande dat je betalings historie niet wijzigt (dat doet de meeste betalingshistorie niet), zou je waarschijnlijk met een

SQL:
1
select max(id) from paymenthistory where idpayment = xx


het meest recente record op kunnen halen. Die kun je dan in de where van je oorspronkelijke query gebruiken.

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 18:03
MacWebber schreef op zondag 24 december 2006 @ 14:07:
Er vanuitgaande dat je betalings historie niet wijzigt (dat doet de meeste betalingshistorie niet), zou je waarschijnlijk met een

SQL:
1
select max(id) from paymenthistory where idpayment = xx


het meest recente record op kunnen halen. Die kun je dan in de where van je oorspronkelijke query gebruiken.
Yep, dat lukt inderdaad! Met een subquery dus :). Ik had er al aan gedacht maar dacht dat het ook zonder subquery zou moeten mogen.
SQL:
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
SELECT
    p.Id, 
    p.MemberId, 
    p.BankAccountNumber, 
    p.Amount, 
    p.NotReceiveBefore, 
    m.FirstName, 
    m.BetweenName, 
    m.LastName, 
    ph.PaymentStatusDate, 
    ps.Name
FROM
    Payment AS p, 
    Member AS m, 
    PaymentHistory AS ph, 
    PaymentStatus AS ps
WHERE
    m.Id = p.MemberId AND
    ph.PaymentId = p.Id AND
    ps.Id = ph.PaymentStatusId AND
    ph.PaymentStatusDate = (
        SELECT 
            MAX(PaymentStatusDate)
        FROM
            PaymentHistory
        WHERE
            PaymentId = p.Id
        )
ORDER BY
    ph.PaymentStatusDate DESC

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik heb je post niet helemaal goed doorgelezen maar kan je niet iets met HAVING doen?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • DexterDee
  • Registratie: November 2004
  • Laatst online: 18:35

DexterDee

I doubt, therefore I might be

Het kan ook zonder subquery, door te sorteren op betaaldatum en dan een limit 1 te doen om alleen de meest recente terug te geven.

Klik hier om mij een DM te sturen • 3245 WP op ZW


  • robbert
  • Registratie: April 2002
  • Laatst online: 01-12 18:50
DexterDee schreef op zondag 24 december 2006 @ 19:35:
Het kan ook zonder subquery, door te sorteren op betaaldatum en dan een limit 1 te doen om alleen de meest recente terug te geven.
En als er nou meerdere betalingen op die datum waren? Dan krijg je er maar 1....

  • DexterDee
  • Registratie: November 2004
  • Laatst online: 18:35

DexterDee

I doubt, therefore I might be

robbert schreef op zondag 24 december 2006 @ 19:42:
[...]

En als er nou meerdere betalingen op die datum waren? Dan krijg je er maar 1....
Als ik de TS lees is hij op zoek naar de laatste betaalstatus. Dat is er altijd maar 1 lijkt me :)

Klik hier om mij een DM te sturen • 3245 WP op ZW


  • MacWebber
  • Registratie: September 2000
  • Niet online
Yep, dat lukt inderdaad! Met een subquery dus :). Ik had er al aan gedacht maar dacht dat het ook zonder subquery zou moeten mogen.
SQL:
1
2
3
4
5
6
        SELECT 
            MAX(PaymentStatusDate)
        FROM
            PaymentHistory
        WHERE
            PaymentId = p.Id
Psies. De reden waarom ik het overigens op ID zou doen is om te voorkomen dat je meerdere records krijgt als er op 1 datum meerdere statussen zijn (niet helemaal ondenkbaar). Als je statusdate ook een tijdsdeel bevat wordt die kans uiteraard al aanzienlijk kleiner.
Pagina: 1