I have two ACCESS tables as follows
CustId CustType 1 Silver 2 Gold 3 Gold
xDate CustId Value 01/01/2020 2 100 01/01/2020 1 50 02/02/2020 2 100 03/01/2020 2 200 03/01/2020 1 50 04/01/2020 2 100 04/01/2020 3 100
I would like to know the total spent between two dates for Gold
customers and set up the following query:
SELECT a.CustId, SUM(t.Value) AS Total FROM Transactions AS t LEFT JOIN ( SELECT CustId FROM Customers WHERE CustType = 'Gold' ) a ON a.CustId = t.CustId WHERE t.xDate BETWEEN #2020/01/03# AND #2020/01/04# AND NOT a.CustId IS NULL GROUP BY a.CustId;
This gives me the following:
2 300 3 100
If I change the query to BETWEEN #2020/01/02# AND #2020/01/03#
I get this:
2 200
Everything is fine so far. However, for the second query I would like to have the total transaction value for Gold
customers as zero (or NULL) even if they have not spent anything during the period ie
2 200 3 0
I believe that I can do this in other dB’s using LEFT OUTER JOIN
but this is not available in ACCESS. This post How do I write a full outer join query in access suggests using UNION
. My attempt was
SELECT c.CustId, 0 as Total FROM Customers c WHERE c.CustType = 'Gold' UNION SELECT t.CustId, SUM(t.Value) AS Total FROM Transactions t WHERE t.xDate BETWEEN #2020/01/03# AND #2020/01/04# GROUP BY t.CustId;
but this produced the following results:
CustId Total 1 50 2 0 2 200 3 0
This result contains all types of customer and has a duplicate for Customer 2. I’m sure the answer is obvious if you know how but I just don’t know how! All suggestions gratefully received – thanks!
Advertisement
Answer
If you want all Gold customers, then Customers
should be the first table in the LEFT JOIN
. There is also no need for a subquery on customers
. However, MS Access does want one on Transactions
:
SELECT c.CustId, NZ(SUM(t.Value)) AS Total FROM Customers as c LEFT JOIN (SELECT t.* FROM Transactions as t WHERE t.xDate BETWEEN #2020/01/03# AND #2020/01/04# ) as t ON t.CustId = c.CustId WHERE c.CustType = 'Gold' GROUP BY c.CustId;