Reputation: 25
Dears, I have a question in MS Access SQL. I have 4 tables.
After Union All and SUMs, to this point I have all the COUNTs of the number of the SUMs. Now I need the SUM of all SUMs by row and by columns. Thank you for your help.
Current result:
ID Name 5/1/2018 5/2/2018 5/3/2018 Count
-- ----- -------- -------- -------- -----
1 Susan 20 30 45 3
2 Juan 15 70 2
3 Tracy 50 60 40 3
4 Jenny 60 8 60 3
5 Bill 100 1
Expected Result:
ID Name 5/1/2018 5/2/2018 5/3/2018 Count E_Total
-- ----- -------- -------- -------- ----- -------
1 Susan 20 30 45 3 95
2 Juan 15 70 2 85
3 Tracy 50 60 40 3 150
4 Jenny 60 8 60 3 128
5 Bill 100 1 100
D_Total 145 168 245 558
Current Query:
select es.EmpID, es.FirstName,
sum(switch(es.DateS = #5/1/2018#, es.Amount)) AS [5/1/2018],
sum(switch(es.DateS = #5/2/2018#, es.Amount)) AS [5/2/2018],
sum(switch(es.DateS = #5/3/2018#, es.Amount)) AS [5/3/2018],
(max(iif(es.DateS = #5/1/2018#, 1, 0)) +
max(iif(es.DateS = #5/2/2018#, 1, 0)) +
max(iif(es.DateS = #5/3/2018#, 1, 0))
) as num_dates
from (
select e.EmpID, e.FirstName, s.DateS, s.Amount
from Employee as e inner join
Sale as s on ( s.EmployeeID = e.EmpID AND s.Amount IS NOT NULL)
where s.DateS between #5/1/2018# and #5/3/2018#
union all
select e1.EmpID, e1.FirstName, s1.DateS, s1.Amount
from Employee1 as e1 inner join
Sale1 as s1 on ( s1.EmployeeID = e1.EmpID and s1.Amount IS NOT NULL)
where s1.DateS between #5/1/2018# and #5/3/2018#
) as es
group by es.EmpID, es.FirstName
order by es.EmpID;
I have the tables and the query pictured here.
As in the picture, The column "E_Total" and row "D_Total are what I need they look like. Or, should I stop here and program the DataGridView in VB.NET to do the job? Thank you very much for your helps or suggestions.
Upvotes: 1
Views: 561
Reputation: 1269463
In another database you would use count(distinct)
. That is not an option in MS Access.
I would write this as:
select es.EmpID, es.FirstName,
sum(switch(es.DateS = #5/1/2018#, es.Amount)) AS [5/1/2018],
sum(switch(es.DateS = #5/2/2018#, es.Amount)) AS [5/2/2018],
sum(switch(es.DateS = #5/3/2018#, es.Amount)) AS [5/3/2018],
(max(iif(es.DateS = #5/1/2018#, 1, 0)) +
max(iif(es.DateS = #5/2/2018#, 1, 0)) +
max(iif(es.DateS = #5/3/2018#, 1, 0))
) as num_dates
from (
select e.EmpID, e.FirstName, s.DateS, s.Amount
from Employee as e inner join
Sale as s on (s.EmployeeID = e.EmpID AND s.Amount IS NOT NULL)
where s.DateS between #5/1/2018# and #5/3/2018#
union all
select e1.EmpID, e1.FirstName, s1.DateS, s1.Amount
from Employee1 as e1 inner join
Sale1 as s1 on (s1.EmployeeID = e1.EmpID and s1.Amount IS NOT NULL)
where s1.DateS between #5/1/2018# and #5/3/2018#
) as es
group by es.EmpID, es.FirstName
order by es.EmpID;
Notes:
select distinct
is almost never used with group by
. You certainly don't need it in this case.Upvotes: 1
Reputation: 32632
You're essentially counting which columns are not null. Because you're counting within a row, the easiest way to do that is just using IIF
statements:
SELECT DISTINCT EmpID, FirstName,
Sum(Switch(q.DateS = #5/1/2018#, q.Amount)) AS [5/1/2018],
Sum(Switch(q.DateS = #5/2/2018#, q.Amount)) AS [5/2/2018],
Sum(Switch(q.DateS = #5/3/2018#, q.Amount)) AS [5/3/2018]
Iif(Sum(Switch(q.DateS = #5/1/2018#, q.Amount)) Is Not Null, 1, 0) +
Iif(Sum(Switch(q.DateS = #5/2/2018#, q.Amount)) Is Not Null, 1, 0) +
Iif(Sum(Switch(q.DateS = #5/3/2018#, q.Amount)) Is Not Null, 1, 0) As [Count]
FROM
(
SELECT u1.EmpID, u1.FirstName, a1.DateS, a1.Amount
FROM Employee AS u1
INNER JOIN Sale AS a1
ON (a1.EmployeeID = u1.EmpID AND a1.Amount IS NOT NULL)
WHERE a1.DateS BETWEEN #5/1/2018# AND #5/3/2018#
UNION ALL
SELECT u2.EmpID, u2.FirstName, a2.DateS, a2.Amount
FROM Employee1 AS u2
INNER JOIN Sale1 a2 ON (a2.EmployeeID = u2.EmpID AND a2.Amount IS NOT NULL)
WHERE a2.DateS BETWEEN #5/1/2018# AND #5/3/2018#
) AS q
GROUP BY q.EmpID, q.FirstName
ORDER BY q.EmpID;
Note that sometimes, you can refer to column names when doing calculations with other calculated columns, e.g. Iif([5/1/2018] Is Not Null
. I don't know the specifics of when that is and isn't allowed in Access, so I tend to avoid it.
Upvotes: 1