Naast de opmerkingen en antwoorden die je al hebt gekregen, geloof ik dat je je procedure enorm ingewikkeld hebt gemaakt. Je doet de dingen heel procedureel, in plaats van in sets te denken zoals je zou moeten zijn. U krijgt ook de geaggregeerde kolommen in drie zoekopdrachten die in wezen identiek zijn (bijvoorbeeld dezelfde tabellen, samenvoegvoorwaarden en predikaten) - u zou ze allemaal kunnen combineren om de drie resultaten in één enkele zoekopdracht te krijgen.
Het lijkt erop dat u probeert in te voegen in de clienthistoricalpurchases-tabel als er nog geen rij voor die client bestaat, anders werkt u de rij bij. Dat schreeuwt voor mij meteen "MERGE statement".
Door dat alles te combineren, denk ik dat uw huidige procedure slechts één enkele samenvoeginstructie zou moeten bevatten:
MERGE INTO clienthistoricalpurchases tgt
USING (SELECT clients.client_id,
COUNT(DISTINCT od.productid) distinct_products,
COUNT(od.productid) total_products,
SUM((od.unitprice * od.quantity) - od.discount) proposed_new_balance
FROM orderdetails od
INNER JOIN orders
ON orderdetails.orderid = orders.orderid
INNER JOIN clients
ON orders.clientid = clients.clientid
GROUP BY clients.client_id) src
ON (tgt.clientid = src.client_id)
WHEN NOT MATCHED THEN
INSERT (tgt.clientid,
tgt.distinctproducts,
tgt.totalproducts,
tgt.totalcost)
VALUES (src.clientid,
src.distinct_products,
src.total_products,
src.proposed_new_balance)
WHEN MATCHED THEN
UPDATE SET tgt.distinctproducts = src.distinct_products,
tgt.totalproducts = src.total_products,
tgt.totalcost = src.proposed_new_balance;
Ik heb echter enkele bedenkingen over uw huidige logica en/of datamodel.
Het lijkt erop dat u verwacht dat er maximaal één rij per klant-ID wordt weergegeven in klanthistorische aankopen. Wat als een client-ID twee of meer verschillende bestellingen heeft? Momenteel zou je elke bestaande rij overschrijven.
Wil je deze logica ook echt toepassen op alle bestellingen elke keer dat het wordt uitgevoerd?