Kan je met SQL (in mijn geval SQLite) ook een eerder berekende waarde hergebruiken?
Voorbeeld:
SELECT
beschrijving,
((strftime('%s', Uren.eindTijd) - strftime('%s', Uren.startTijd)) / 3600.0) as aantal,
aantal * Tarieven.prijsPerUur as prijs
FROM
Uren
JOIN
Tarieven ON Uren.tariefId = Tarieven.id
Hier is 'aantal' het aantal uur dat ik ergens aan heb gewerkt, en deze wil ik apart op mijn factuur hebben staan. Daarnaast wil ik ook de prijs voor dat uur hebben, dat wordt berekend door het aantal uur te vermenigvuldigen met de prijsPerUur.
Maar het aantal uur heb ik al uitgerekend, ik hoef hem dus alleen nog maar te vermenigvuldigen. Echter kan ik 'aantal' niet gebruiken in mijn query (kolom niet gevonden) en ben ik bang dat ik die 'hele berekening' (het gaat om het principe) weer helemaal overnieuw moet doen.
Bij mijn weten zul je dan met een stored procedure moeten gaan werken. Je kunt de alias namelijk niet nogmaals binnen het SELECT-gedeelte gebruiken. Je kunt er bv. wel op sorteren e.d. , maar binnen de SELECT is het niet bruikbaar. Je zult dit soort zaken dus elders moeten berekenen of meerdere keren moeten berekenen binnen dezelfde query.
Maar ik zie niet in hoe stored procedures, wat eigenlijk simpel gezegd niet meer is dan het benoemen en verplaatsen van een berekening, mij hierbij kunnen helpen. Ik zal dan alsnog 2 maal de procedure aan moeten roepen, en dus is het waarschijnlijk dat de berekening alsnog 2 maal wordt uitgevoerd. Tenzij de database de resultaten cached, wat mij niet logisch lijkt.
Een andere optie is een View maken waarbij ik alle data uit de tabel Uren + deze extra kolom 'aantal' neem. Ik denk dat dat de meest nette oplossing is, al vraag ik me af of dat niet onder het kopje 'overkill' valt. Want dan wordt eerst de view gemaakt, waarbij de berekening op alle records wordt uitgevoerd terwijl ik er misschien (waarschijnlijk!) maar een paar nodig heb. Het filteren op basis van het WHERE gedeelte gebeurt immers achteraf, anders zou je niet kunnen filteren op de resultaten in de View. Ook geen goeie oplossing als het om performance gaat dus.
Kutzooi. Waarom konden programmeurs, die de hele dag werken met variabelen nu niet even een soort van variabelen maken in de SQL standaard. Ik begin serieus te twijfelen aan de onder andere door jouw zo gepropageerde 'kracht van databases' als ze al niet eens dit soort standaard-stuff kunnen.
/me wacht nog altijd op een 'native' oplossing, een oplossing waarbij het lijkt alsof je gewoon objecten in het geheugen propt en ze er op een gegeven moment in precies dezelfde vorm uit komen.
Zonder LOOP kun je overigens ook variabelen een waarde geven en daar wat mee gaan doen. Dat is niet iets dat specifiek aan een LOOP is gekoppeld.
Edit: Hier nog even een eenvoudig voorbeeldje:
CREATE OR REPLACE FUNCTION scripts.get_db(IN name text, OUT db text) AS
$BODY$
DECLARE
user text = name;
BEGIN
IF (user = 'pgFrank')
THEN db = 'pgSQL';
ELSEIF (user = 'Jelmer')
THEN db = 'SQLite';
ELSE
db = 'MySQL';
END IF;
RETURN;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Je roept hem aan met
SELECT scripts.get_db('Jelmer');
Het is slechts een voorbeeldje, geen commentaar s.v.p. ;)