简体   繁体   中英

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. 查询问题

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, eg 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM