SQL语句加入CASE

时间:2015-10-06 11:09:25

标签: ms-access

我从MS ACCESS下面的这个3表有问题“SQL CASE IF ELSE”,我不知道如何开始。

表A(注册)

Name    | Desc      | Amount    | Year
NameA   | JAN&NOV   | 100.00    | 2015
NameA   | BOOKS     | 70.00     | 2015
NameA   | UNIFORM   | 100.00    | 2015
NameB   | JAN&NOV   | 100.00    | 2015

表B(Montly Payment and Others)

Name    | Desc      | Amount    | Year
NameA   | PAY FEB   | 100.00    | 2015
NameB   | PAY MAC   | 100.00    | 2015
NameA   | PAY MAC   | 100.00    | 2015
NameB   | OTHERS    | 20.00     | 2015
NameB   | PAY APR   | 100.00    | 2015

表C(学生名单)

Name    | Year      | Class 
NameA   | 2015      | A 
NameB   | 2015      | B

结果:

Name    | Year  | Class | Jan&Nov   | Pay Feb   | Pay Mac   | Pay Apr
NameA   | 2015  | A     | 100.00    | 100.00    | 100.00    | 000.00
NameB   | 2015  | B     | 100.00    | 100.00    | 100.00    | 100.00

我需要创建字段Pay Jan& Nov,Pay Feb到Pay 10月,数据基于此3表。如果数据不存在,我需要将其格式化为“00.00”或“NOT PAID”。

我希望任何有解决方案的人都能帮助我。我实际上是SQL语句的新手。

3 个答案:

答案 0 :(得分:0)

这是直接使用子查询而不是聚合和案例构造的解决方案。 (我使用NZ在NULL的情况下返回0。这将是标准SQL中的COALESCE。)

select 
  name, 
  year,
  class,
  (
    select nz(sum(r.amount), 0)
    from registrations r 
    where r.name = s.name
    and r.year = s.year
    and r.desc = 'JAN&NOV'
  ) as "Jan&Nov",
  (
    select nz(sum(r.amount), 0)
    from monthly m 
    where m.name = s.name
    and m.year = s.year
    and desc = 'PAY FEB'
  ) as "Pay Feb",
  ...
from student_list s;

这与连接,聚合和IIF(在标准SQL中将是CASE)相同:

select 
  s.name, 
  s.year,
  s.class,
  nz(max(r.amount), 0) as "Jan&Nov",
  nz(max(iif(m.desc = 'PAY FEB', m.amount end, null)), 0) as "Pay Feb",
  ...
from student_list s
left join
(
  select 
    name, 
    year,
    sum(amount) as amount
  from registrations
  where desc = 'JAN&NOV'
  group by name, year
) r on r.name = s.name and r.year = s.year
left join
(
  select 
    name, 
    year,
    desc,
    sum(amount) as amount
  from monthly
  where group by name, year, desc
) m on m.name = s.name and m.year = s.year
group by s.name, s.year, s.class;

(你可能需要或者可能不需要在连接周围添加额外的括号。我想我记得MS Access在连接语法方面非常特殊。)

至于以某种格式显示数字:这是您通常在GUI层中执行的操作。当使用SQL作为格式时,您必须将纯数字转换为字符串,例如20进入' 20.00'在MS Access中,您可以使用FORMAT:

执行此操作
format (value, 'Standard')

使用第二个查询:

format(nz(max(iif(m.desc = 'PAY FEB', m.amount end, null)), 0), 'Standard')

显示' 0.00'如果是NULL。或者:

nz(format(max(iif(m.desc = 'PAY FEB', m.amount, null)), 'Standard'), 'NOT PAID')

显示“没有付款”#39;如果是NULL。

答案 1 :(得分:0)

关于TableATableB与gheter相关的问题并不是很清楚,但看起来您想要UNION ALL查询并且想要排除某些类别:

SELECT
  c.Name,
  c.Year,
  c.Class,
  ab.Desc,
  ab.Amount
FROM
  TableC AS C INNER JOIN (
    SELECT * FROM TableA WHERE Desc NOT IN ('BOOKS', 'UNIFORM', 'OTHERS')
    UNION ALL
    SELECT * FROM TableB WHERE Desc NOT IN ('BOOKS', 'UNIFORM', 'OTHERS')
  ) AS ab
  ON c.Name = ab.Name AND c.Year = ab.Year

然后您可以使用前一个查询作为子查询使用Pivot:

TRANSFORM Sum(Amount) AS SumOfAmount
SELECT Name, Year, Class, Sum(Amount) AS [Sum_Amount]
FROM (

  ...the query above...

) AS s
GROUP BY Name, Year, Class
PIVOT Desc;

答案 2 :(得分:0)

感谢fthiella,DeadZone,Beth和Thorsten Kettner给我一个正确的方向。由于尝试了很多天直接在MS Access IDE上使用您的解决方案,我终于找到了一个技巧。我非常感谢你解决我的问题。诀窍是: -

A)如果SELORD记录是空的或存在,那么使用(选择Nz(MAX(m.amount),' NOT PAID')作为PAYFEB。

LEFT JOIN或Direct SUBQUERIES等所有类型的解决方案实际上都在运作。但我更喜欢SUBQUERIES因为更多的组织,我可以看到是否有任何语法或字段没有注册。

最后,如果没有你的支持,我无法得到这个问题的答案。非常感谢你们。