Förutom kommentarerna och svaren du redan har fått, tror jag att du har överkomplicerat ditt förfarande enormt. Du gör saker mycket procedurmässigt, snarare än att tänka i uppsättningar som du borde vara. Du får också de aggregerade kolumnerna i tre frågor som är i huvudsak identiska (t.ex. samma tabeller, sammanfogningsvillkor och predikat) - du kan kombinera dem alla för att få de tre resultaten i en enda fråga.
Det ser ut som att du försöker infoga i tabellen för klienthistoriska köp om en rad inte redan finns för den klienten, annars uppdaterar du raden. Det skriker omedelbart "MERGE statement" till mig.
Om jag kombinerar allt detta, tror jag att din nuvarande procedur bara bör innehålla ett enda sammanslagningsuttryck:
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;
Jag har dock en del oro över din nuvarande logik och/eller datamodell.
Det verkar som om du förväntar dig att högst en rad per kund-id ska visas i kundhistoriska inköp. Vad händer om ett kund-ID har två eller flera olika beställningar? För närvarande skulle du skriva över alla befintliga rader.
Dessutom, vill du verkligen tillämpa denna logik på alla beställningar varje gång den körs?