В допълнение към коментарите и отговорите, които вече сте получили, смятам, че значително сте усложнили процедурата си. Вие правите нещата много процедурно, вместо да мислите на групи, както трябва. Освен това получавате обобщените колони в три заявки, които по същество са идентични (напр. едни и същи таблици, условия за свързване и предикати) – можете да ги комбинирате всички, за да получите трите резултата в една заявка.
Изглежда, че се опитвате да вмъкнете в таблицата clienthistoricalpurchases, ако ред все още не съществува за този клиент, в противен случай актуализирате реда. Това незабавно ми извиква "MERGE statement".
Комбинирайки всичко това, мисля, че настоящата ви процедура трябва да съдържа само един оператор за сливане:
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;
Въпреки това имам някои притеснения относно текущата ви логика и/или модел на данни.
Изглежда, че очаквате най-много един ред на clientid да се появи в clienthistoricalpurchases. Какво ще стане, ако един clientid има две или повече различни поръчки? В момента бихте презаписали всеки съществуващ ред.
Също така, наистина ли искате да приложите тази логика във всички поръчки всеки път, когато се стартира?