Tony Nguyen
Tony Nguyen

Reputation: 25

SUM of the SUMs in MS Access SQL

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. Query Problem

Upvotes: 1

Views: 561

Answers (2)

Gordon Linoff
Gordon Linoff

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.
  • When you give tables aliases, use table abbreviations for the alias. It makes the query much easier to follow.
  • Qualify all column names, not just some of them.

Upvotes: 1

Erik A
Erik A

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

Related Questions