Ud over de kommentarer og svar, du allerede har fået, mener jeg, at du har overkompliceret din procedure massivt. Du gør tingene meget proceduremæssigt i stedet for at tænke i sæt, som du burde være. Du får også de aggregerede kolonner i tre forespørgsler, der i det væsentlige er identiske (f.eks. samme tabeller, sammenføjningsbetingelser og prædikater) - du kan kombinere dem alle for at få de tre resultater i en enkelt forespørgsel.
Det ser ud til, at du forsøger at indsætte i tabellen klienthistoriske køb, hvis der ikke allerede findes en række for den klient, ellers opdaterer du rækken. Det skriger med det samme "MERGE statement" til mig.
Ved at kombinere alt det, tror jeg, at din nuværende procedure kun skal indeholde en enkelt flettesætning:
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;
Jeg har dog nogle bekymringer over din nuværende logik og/eller datamodel.
Det ser ud til, at du forventer, at der højst vises én række pr. kunde-id i kundehistoriske køb. Hvad hvis et klient-id har to eller flere forskellige ordrer? I øjeblikket vil du overskrive enhver eksisterende række.
Vil du også virkelig anvende denne logik på tværs af alle ordrer, hver gang den køres?