Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WHERE CLAUSULE op 'AS' veld?

0 views
Skip to first unread message

Martin

unread,
Mar 18, 2010, 1:21:23 PM3/18/10
to
Hallo allemaal,

Ik heb een query waar ik rekeningen lees, en per rekening de sommen van de
betalingen.
Dan bereken ik het saldo en dit berekende veld wil ik dan in de 'WHERE'
clausule opnemen.

De query ziet er zo uit:

SELECT BIL.BIL_ID, (BIL.AMOUNT_BIL - SUM(BILPAY.AMOUNT_PAY) -
SUM(BILPAY.AMOUNT_DISC)) AS FC_BALANCE
FROM BIL
LEFT OUTER JOIN BILPAY ON BIL.BIL_ID = BILPAY.BIL_ID
WHERE FC_BALANCE <> 0
GROUP BY BIL.BIL_ID, BIL.BILTYP_ID, BIL.BPA_ID, BIL.AMOUNT_BIL
ORDER BY BIL.BIL_ID

En dat mag niet...
Ik krijg de foutmelding dat FC_BALANCE een onbekende kolom is.

Als ik 't zo probeer:
WHERE (BIL.AMOUNT_BIL - SUM(BILPAY.AMOUNT_PAY) - SUM(BILPAY.AMOUNT_DISC)) <>
0

krijg ik de foutmelding dat aggregate functions niet toegestaan zijn in de
'WHERE' clausule

Hoe moet ik zoiets dan wel doen?

Bvd,
Martin

Hugo Kornelis

unread,
Mar 19, 2010, 7:07:34 AM3/19/10
to

Hoi Martin,

Dat dit niet mag komt door de logische volgorde waarin een query wordt
verwerkt:

1. Samenvoegen van alle tabellen uit de FROM
2. Filteren met behulp van de WHERE
3. Vormen van groepen als een GROUP BY gebruikt is
4. Filteren van groepen met behulp van de HAVING
5. Samenstellen van de kolommen in het resultaat op basis van de SELECT
lijst
6. Sorteren van het resultaat op basis van ORDER BY

(De werkelijke volgorde kan anders zijn als de optimizer denkt dat dit
efficiënter is, zolang het resultaat maar gelijk is)

Zoals je aan die volgorde kan zien, is "FC_BALANCE" nog niet bekend op
het moment dat de WHERE moet worden geëvalueerd.

De oplossing is het herhalen van de formule in de WHERE. Alleen dat gaat
in jouw geval ook niet, omdat je een aggregaat gebruikt - in dat geval
moet je de berekening herhalen in de HAVING. Je krijgt dan dus:

SELECT BIL.BIL_ID,
BIL.AMOUNT_BIL
- SUM(BILPAY.AMOUNT_PAY)
- SUM(BILPAY.AMOUNT_DISC) AS FC_BALANCE


FROM BIL
LEFT OUTER JOIN
BILPAY
ON BIL.BIL_ID = BILPAY.BIL_ID

GROUP BY BIL.BIL_ID, BIL.BILTYP_ID, BIL.BPA_ID, BIL.AMOUNT_BIL

HAVING BIL.AMOUNT_BIL
- SUM(BILPAY.AMOUNT_PAY)
- SUM(BILPAY.AMOUNT_DISC) <> 0
ORDER BY BIL.BIL_ID;

PS: Gebruik van alleen uppercase voor tabelnamen en kolomnamen is een
slechte gewoonte, omdat de code daardoor veel moeilijker te lezen wordt.
Meestal wordt de zogenaamde "CamelCase" gebruikt: kleine letter en
hoofdletters aan het begin van een woord, ook als in de naam meerdere
woorden achter elkaar staan. Dan hoef je ook geen underscore karaters
meer te gebruiken. Je krijgt dan bv de tabel "Bills" en de kolom
"AmountBill" (dus in de query: Bills.AmountBill)

--
Hugo Kornelis, SQL Server MVP
My SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis

Martin

unread,
Mar 20, 2010, 4:19:35 AM3/20/10
to
Hoi Hugo,

Heel hartelijk dank voor je duidelijke antwoord.

Overigens, CamelCase heeft normaal ook mijn voorkeur, maar voor dit
specifieke (reeds bestaande) systeem heb ik geen keus.

Groetjes,
Martin

"Hugo Kornelis" <hugo@pe_NO_rFact.in_SPAM_fo> wrote in message
news:17m6q51e1pur9r8pv...@4ax.com...

0 new messages