In article <1163788003.27692.0@proxy00.news.clara.net>,
no.way@jose says...
Quote:
>
I am trying to write an SQL UPDATE statement for an MSAccess table and
am having some problems getting my head around it. Can anyone help?
>
TableName: CustTransactions
TransactionKey AutoNumber (Primary Key)
CustomerID Long Integer (Non-unique index)
AmountSpent Double
CustSelected Boolean
>
What I would like to do is, for all of the records in descending order
of "AmountSpent" where "CustSelected = TRUE", set CustSelected to FALSE
such that the sum of all the AmountSpent records is no greater than a
specified amount (say $50,000).
>
What I'm doing at the moment is a "SELECT * FROM CustTransactions WHERE
CustSelected = TRUE ORDER BY AmountSpent;", programatically looping
through all the records until AmountSpent 50000, then continuine to
loop through the remainder of the records setting CustSelected = FALSE.
This works but is slow and inefficient. I just know it could be done in
a single SQL statement with subqueries, but I can't figure it out.
>
The closest I can get is:-
>
UPDATE CustTransactions SET CustSelected = FALSE
WHERE (CustSelected = TRUE)
AND TransactionKey NOT IN
(SELECT TOP 50000 TransactionKey FROM CustTransactions WHERE
(((CustTransactions.CustSelected)=TRUE))
ORDER BY AmountSpect DESC, TransactionKey ASC);
>
However, this mereley ensures only the top 50,000 customers by amount
spent are "selected", not the top "X" customers who have spent a total
of $50,000. I really need to replace the "SELECT TOP 50000" with some
form of "SELECT TOP (X rows until sum(AmountSpent) =50000)".
>
Is it even possible to achieve what I'm trying to do?
>
Thanks in advance for any assistance offered!
>
really need to replace the "SELECT TOP 50000" with some
>form of "SELECT TOP (X rows until sum(AmountSpent) =50000)".
It seems that this is asking for both a ranking and a running
sum and
may require two queries.
SELECT CustTransactions.TransactionKey,
CustTransactions.CustomerID,
CustTransactions.AmountSpent,
CustTransactions.CustSelected,
(SELECT COUNT(* )
FROM CustTransactions AS ct2
WHERE CustTransactions.AmountSpent < ct2.AmountSpent
OR (CustTransactions.AmountSpent = ct2.AmountSpent
AND CustTransactions.TransactionKey <=
ct2.TransactionKey)) AS Rank
FROM CustTransactions
WHERE CustTransactions.CustSelected = True;
UPDATE CustTransactions SET CustSelected = FALSE
WHERE TransactionKey = ANY (SELECT a.TransactionKey
FROM Ranked_Customer_Transactions AS a
INNER JOIN Ranked_Customer_Transactions AS b
ON b.Rank <= a.Rank
GROUP BY a.TransactionKey
HAVING SUM(b.AmountSpent) <= [Enter dollar amount:]);