3个表,2个外键,按月计算

时间:2013-11-24 00:47:36

标签: sql sql-server

我需要帮助才能获得正确的输出。我有一个费用类别(1个表格,主要类别如“医疗”)和相关的费用子类别(如“检查”,“治疗”等)。这些由pcatid和pcatid_fk绑在一起。通过引用类别(pcatid_fk)和子类别(psubcatid_fk)对persexpenses进行条目。我的查询产生一个结果,其中费用金额显示在显示类别+子类别的每一行中。

在这个例子中,我已经在4月份参加了500美元的考试。这是输出的样子:

当前结果

Category    Subcategory     Jan         Feb          April
Medical     Exam            NULL        NULL         500.000
Medical     Therapy         NULL        NULL         500.000
Medical     Test            NULL        NULL         500.000

它应该是什么样子:

期望的结果

Category    Subcategory     Jan         Feb          April
Medical     Exam            NULL        NULL         500.000
Medical     Therapy         NULL        NULL         NULL
Medical     Test            NULL        NULL         NULL

到目前为止,这是我的查询:

SELECT Isnull(second.pcategory, 0)   AS CATEGORY,
   Isnull(third.psubcategory, 0) AS SUBCATEGORY,
   Isnull(first.jan, 0)          AS JAN,
   Isnull(first.feb, 0)          AS FEB,
   Isnull(first.mar, 0)          AS MAR,
   Isnull(first.apr, 0)          AS APR,
   Isnull(first.may, 0)          AS MAY,
   Isnull(first.jun, 0)          AS JUN,
   Isnull(first.jul, 0)          AS JUL,
   Isnull(first.aug, 0)          AS AUG,
   Isnull(first.sep, 0)          AS SEP,
   Isnull(first.oct, 0)          AS OCT,
   Isnull(first.nov, 0)          AS NOV,
   Isnull(first.dec, 0)          AS DEC,
   Isnull(first.q1, 0)           AS Q1,
   Isnull(first.q2, 0)           AS Q2,
   Isnull(first.q3, 0)           AS Q3,
   Isnull(first.q4, 0)           AS Q4,
   Isnull(first.annual, 0)       AS ANNUAL
FROM   (SELECT pcategory,
           pcatid
    FROM   sky.dbo.persexpcategories) second
   LEFT JOIN (SELECT psubcategory,
                     pcatid_fk
              FROM   sky.dbo.persexpsubcat) third
          ON second.pcatid = third.pcatid_fk
   LEFT JOIN (SELECT pcategory,
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '1' THEN pexpamount
                                END), 0) AS 'jan',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '2' THEN pexpamount
                                END), 0) AS 'feb',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '3' THEN pexpamount
                                END), 0) AS 'mar',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '4' THEN pexpamount
                                END), 0) AS 'apr',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '5' THEN pexpamount
                                END), 0) AS 'may',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '6' THEN pexpamount
                                END), 0) AS 'jun',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '7' THEN pexpamount
                                END), 0) AS 'jul',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '8' THEN pexpamount
                                END), 0) AS 'aug',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '9' THEN pexpamount
                                END), 0) AS 'sep',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '10' THEN
                                  pexpamount
                                END), 0) AS 'oct',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '11' THEN
                                  pexpamount
                                END), 0) AS 'nov',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) = '12' THEN
                                  pexpamount
                                END), 0) AS 'dec',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) BETWEEN '1' AND '3'
                                THEN
                                  pexpamount
                                END), 0) AS 'Q1',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) BETWEEN '4' AND '6'
                                THEN
                                  pexpamount
                                END), 0) AS 'Q2',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) BETWEEN '7' AND '9'
                                THEN
                                  pexpamount
                                END), 0) AS 'Q3',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) BETWEEN '10' AND '12'
                                THEN
                                  pexpamount
                                END), 0) AS 'Q4',
                     Isnull(Sum(CASE
                                  WHEN Month(pexpdate) BETWEEN '1' AND '12'
                                THEN
                                  pexpamount
                                END), 0) AS 'annual'
              FROM   sky.dbo.users
                     LEFT JOIN sky.dbo.persexpenses
                            ON userid = userid_fk
                     LEFT JOIN sky.dbo.persexpcategories
                            ON pcatid_fk = pcatid
              WHERE  userid = '1'
              GROUP  BY pcategory) first
          ON second.pcategory = first.pcategory  

表格/ [字段]是:

persexpenses

  • [pexpid]
  • [pexpdate]
  • [pexpamount]
  • [pcatid_fk]
  • [psubcatid_fk]

persexpcategories

  • [pcatid]
  • [pcategory] ​​

persexpsubcat

  • [psubcatid]
  • [psubcategory] ​​
  • [pcatid_fk]

1 个答案:

答案 0 :(得分:1)

尝试这样的事情,我已经对表进行了修改但不确定哪个列来自哪些表,因此如果不明确,您还需要使用带有列名的别名。

SELECT 
   PC.pcategory                     AS CATEGORY,
   PSC.psubcategory                 AS SUBCATEGORY,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 1 THEN pexpamount ELSE NULL END), 0) AS JAN,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 2 THEN pexpamount ELSE NULL END), 0) AS FEB,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 3 THEN pexpamount ELSE NULL END), 0) AS MAR,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 4 THEN pexpamount ELSE NULL END), 0) AS APR,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 5 THEN pexpamount ELSE NULL END), 0) AS MAY,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 6 THEN pexpamount ELSE NULL END), 0) AS JUN,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 7 THEN pexpamount ELSE NULL END), 0) AS JUL,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 8 THEN pexpamount ELSE NULL END), 0) AS AUG,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 9 THEN pexpamount ELSE NULL END), 0) AS SEP,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 10 THEN pexpamount ELSE NULL END), 0)AS OCT,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 11 THEN pexpamount ELSE NULL END), 0)AS NOV,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 12 THEN pexpamount ELSE NULL END), 0)AS DEC,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 1 OR MONTH(pexpdate) = 2 OR
                MONTH(pexpdate) = 3 THEN pexpamount ELSE NULL END), 0)         AS Q1,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 4 OR MONTH(pexpdate) = 5 OR
                MONTH(pexpdate) = 6 THEN pexpamount ELSE NULL END), 0)         AS Q2,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 7 OR MONTH(pexpdate) = 8 OR
                MONTH(pexpdate) = 9 THEN pexpamount ELSE NULL END), 0)         AS Q3,
   Isnull(SUM(CASE WHEN MONTH(pexpdate) = 10 OR MONTH(pexpdate) = 11 OR
                MONTH(pexpdate) = 12 THEN pexpamount ELSE NULL END), 0)        AS Q4,
   Isnull(SUM(pexpamount), 0)       AS ANNUAL
FROM  psersexpenses P LEFT JOIN sky.dbo.persexpcategories PC
ON    P.pcatid = PC.pcatid
LEFT JOIN sky.dbo.persexpsubcat PSC
ON P.psubcatid_fk = PSC.psubcatid
GROUP BY PC.pcategory,PSC.psubcategory