I forgot that aggregate functions always need the AS...
No, but if you don't use the alias, then the result field will be called EXPR001 or some such random designation. You need to give it a specific name if you're going to use it elsewhere.
The problem wasn't AVG, it was what you had to have in order to average anything. Your prior code was summing all transactions together for each customer. I had to do an intermediate step that summed up EACH transaction for each customer (Bold Green code). Since I didn't need the transaction ID for anything, I left out the bold purple code, but the field was there implicitly because of the GROUP BY clause.
Code:
SELECT
CUSTOMER.NAME,
Avg(TransactionTotal) As AvgTransaction
FROM
(SELECT
CUSTOMER.NAME,
[SALES TRANSACTIONS].[SALES TRANSACTION ID],
Sum(SUBTRANSACTIONS.QUANTITY*PRODUCT.[PRODUCT PRICE]*DISCOUNT.[DISCOUNT AMOUNT]) AS TransactionTotal
FROM
( ( DISCOUNT
INNER JOIN
(CUSTOMER
INNER JOIN
[SALES TRANSACTIONS]
ON CUSTOMER.[CUSTOMER ID] = [SALES TRANSACTIONS].[CUSTOMER ID])
ON DISCOUNT.[DISCOUNT ID] = [SALES TRANSACTIONS].[DISCOUNT ID]
)
INNER JOIN
( PRODUCT
INNER JOIN
SUBTRANSACTIONS
ON PRODUCT.[PRODUCT ID] = SUBTRANSACTIONS.[PRODUCT ID]
)
ON [SALES TRANSACTIONS].[SALES TRANSACTION ID] = SUBTRANSACTIONS.[SALES TRANSACTION ID]
GROUP BY CUSTOMER.[CUSTOMER NAME], [SALES TRANSACTIONS].[SALES TRANSACTION ID]
)
GROUP BY CUSTOMER.[CUSTOMER NAME]
);
As a general rule, if it's all inner joins, I prefer to nest them in a way that it looks simpler -
Code:
FROM
( ( ( ( (
PRODUCT
INNER JOIN SUBTRANSACTIONS
ON PRODUCT.[PRODUCT ID] = SUBTRANSACTIONS.[PRODUCT ID]
)
INNER JOIN [SALES TRANSACTIONS]
ON [SALES TRANSACTIONS].[SALES TRANSACTION ID] = SUBTRANSACTIONS.[SALES TRANSACTION ID])
)
INNER JOIN CUSTOMER
ON CUSTOMER.[CUSTOMER ID] = [SALES TRANSACTIONS].[CUSTOMER ID]
)
INNER JOIN DISCOUNT
ON DISCOUNT.[DISCOUNT ID] = [SALES TRANSACTIONS].[DISCOUNT ID]
)
GROUP BY CUSTOMER.[CUSTOMER NAME], [SALES TRANSACTIONS].[SALES TRANSACTION ID]
)
And I Prefer to Alias the tables for readability and conciseness
Code:
FROM
( ( ( ( (
PRODUCT AS TP
INNER JOIN SUBTRANSACTIONS AS TSub
ON TP.[PRODUCT ID] = TSub.[PRODUCT ID]
)
INNER JOIN [SALES TRANSACTIONS] AS TS
ON TS.[SALES TRANSACTION ID] = TSub.[SALES TRANSACTION ID])
)
INNER JOIN CUSTOMER AS TC
ON TC.[CUSTOMER ID] = TS.[CUSTOMER ID]
)
INNER JOIN DISCOUNT AS TD
ON TD.[DISCOUNT ID] = TS.[DISCOUNT ID]
)
GROUP BY TC.[CUSTOMER NAME], TS.[SALES TRANSACTION ID]
)
That's my preferences, but your mileage may vary.
From my research, it seems that I have to remove the checkbox for “Referential Integrity” in the table relationships.
No, you have to make sure that all the subtransactions are deleted before you delete the transaction record. If you delete the transaction without deleting them, then those orphaned subtransactions just sit there forever, and... YES...cause all the problems that you are envisioning.
The key to this is (as ItsMe said) to enforce that constraint programmatically - use a command button to delete, and in the Onclick event VBA, delete the subtransactions, then delete the transaction.