简体   繁体   English

SQL分组依据和聚合在两列中

[英]SQL group by and aggregation in two columns

This is a follow up on my previous question, kindly answered by @Barmar: When using MYSQL GROUP BY WITH ROLLUP on Year(date) and Month(date) i am not able to change Null to 'Total' 这是我之前的问题的后续工作,由@Barmar很好地回答: 在Year(date)和Month(date)上使用MYSQL GROUP BY WITH ROLLUP时,我无法将Null更改为“ Total”

I have a SQL query which gets data from my transaction , subkategori , and kategori tables and this works fine. 我有一个SQL查询,从我的交易 ,subkategori和表驾驶员学校获取数据,并能正常工作。 But now I want to add budget table and sum the budgeted amount. 但是现在我想添加预算表并汇总预算金额。 My approach is as below: 我的方法如下:

$stmt = $dbh->prepare("
                SELECT IFNULL(Year, 'All') AS Year,
                       IFNULL(Month, 'All') AS Month,
                       IFNULL(Kategori,'All') AS Kategori,
                       IFNULL(Subkategori,'All') AS Subkategori,
                       Belopp,
                       Budget
                FROM (
                      SELECT YEAR(transaktioner.datum) AS Year,
                             MONTH(transaktioner.datum) AS Month,
                             kategori.kat_namn AS Kategori,
                             subkategori.subkat_namn AS Subkategori,
                             SUM(transaktioner.belopp)  AS Belopp,
                             SUM(budget.budgetedAmmount) AS Budget

                      FROM subkategori
                      LEFT JOIN transaktioner 
                            ON subkategori.subkat_id=transaktioner.subkat_id
                      LEFT JOIN kategori
                            ON subkategori.kat_id = kategori.kat_id
                      LEFT JOIN budget
                            ON subkategori.subkat_id = budget.subkat_id

                      GROUP BY Year, Month, Kategori, Subkategori
                      WITH ROLLUP

                    ) AS x


                    WHERE Year =".$year." 

                    ");

It gives me a null output. 它给了我一个null输出。 Can somebody help me with this one? 有人可以帮我吗?

Tables are as follows: 表格如下:

transaktioner 转译者

id
datum
beskrivning
overforing
belopp
balans
subkat_id
konto_id
latest_update

kategori ori

kat_id
kat_namn
type
latest_update

subkategori 子立

subkat_id
subkat_namn
kat_id
latest_update

Budget table 预算表

budget_id
subkat_id
budgetedAmmount
user_id
year

DESIRED Result table 期望结果表

Year    Month   Kategory    Subkategory     Spent   Budget
2017    1       Kat1        Subkat1         1000    500
2017    1       Kat1        Subkat2         500     250
2017    1       kat1        ALL             1500    750
2017    1       Kat2        Subkat1         2000    1000
2017    1       Kat2        Subkat2         450     500
2017    1       kat2        ALL             2450    1500
2017    1        ALL        ALL             3950    2250
ALL     ALL      ALL        ALL             3950    2250

See fiddle: http://sqlfiddle.com/#!9/35a778/2 参见小提琴: http ://sqlfiddle.com/#!9/ 35a778/2

This might help lead to an answer, here goes 这可能会帮助您找到答案

  1. Move the where clause 移动where子句

      SELECT YEAR(transaktioner.datum) AS Year, MONTH(transaktioner.datum) AS Month, kategori.kat_namn as Kategori, subkategori.subkat_namn as Subkategori, SUM(transaktioner.belopp) AS Belopp, SUM(budget.budgetedAmmount) AS Budget FROM subkategori Left JOIN transaktioner ON subkategori.subkat_id=transaktioner.subkat_id Left JOIN kategori ON subkategori.kat_id = kategori.kat_id LEFT JOIN budget ON subkategori.subkat_id = budget.subkat_id > here >> WHERE ??? GROUP BY Year, Month,Kategori,Subkategori WITH ROLLUP 
  2. Run that partial query in MySQL directly, if you get a result 如果得到结果,则直接在MySQL中运行该部分查询

  3. run the complete query in MySQL, if you get a result 如果得到结果,请在MySQL中运行完整的查询

  4. check that your PHP is injecting the year parameter correctly, just output the generated query code, and try to run that in MySQL 检查您的PHP是否正确注入year参数,仅输出生成的查询代码,然后尝试在MySQL中运行

I'm out at this point, debugging PHP isn't "my thing" 我到此为止,调试PHP并不是“我的事”

Oh, just one small point the ANSI SQL equivalent function to IFNULL() is COALESCE(). 哦,与NULL对应的ANSI SQL等效函数只有一点是COALESCE()。 While IFNULL() is fine in MySQL I would encourage you to use COALESCE() instead but you don't have to obviously. 尽管在MySQL中IFNULL()很好,但我还是鼓励您使用COALESCE(),但是您不必这样做。

With some transactions monthly, and budget annually, there hs to be some method to spread he budget "per month". 由于每月进行一些交易,而每年进行预算,因此,有某种方法可以“每月”分配预算。 Also to ensure all sub categories and all months are reported create a "Cartesian product" of those, then left join the data to that. 同样,要确保报告所有子类别和所有月份,请创建这些子类别的“笛卡尔积”,然后将数据与该类别合并。 Finally in addition you need to include a way to sort the data sensibly. 最后,您还需要包括一种对数据进行合理排序的方法。 I hope that from this example you can adapt it to your specific needs. 我希望从这个例子中您可以使其适应您的特定需求。

SQL Fiddle SQL小提琴

MySQL 5.6 Schema Setup : MySQL 5.6模式设置

-- Create transaktioner 
  CREATE TABLE transaktioner
      (`id` varchar(4),
      `datum` date,
      `beskrivning` varchar(8),
      `overforing` varchar(8),
      `belopp` varchar(8),
      `balans` varchar(8),
      `subkat_id` varchar(8),
      `konto_id` varchar(8)
       );

  INSERT INTO transaktioner
      ( `datum`,`beskrivning`,`overforing`,`belopp`,`balans`,`subkat_id`,`konto_id`)
  VALUES
      ("2017-01-01","Test1","Yes",'1000','1200','1','1111'),
      ("2016-01-01","Test1","Yes",'1000','1200','2','1111');

-- Create Kategori Table
  CREATE TABLE kategori
      (`kat_id` varchar(4),`kat_namn` varchar(10));

  INSERT INTO kategori
      ( `kat_id`,`kat_namn`)
  VALUES
      ('1',"Kat1"),
      ('2',"Kat2"),
      ('3',"Kat3"),
      ('4',"Kat4");


-- Create Subkategori Table   
  CREATE TABLE subkategori
      (`subkat_id` varchar(4),`kat_id` varchar(4),`subkat_namn` varchar(10));

  INSERT INTO subkategori
      ( `subkat_id`,`kat_id`,`subkat_namn`)
  VALUES
      ('1','1',"subKat1"),
      ('2','1',"subKat2"),
      ('3','1',"subKat3"),
      ('4','1',"subKat4");    

-- Create budget Table   
  CREATE TABLE budget
      (`budget_id` varchar(4),`subkat_id` varchar(4),`budgetedAmmount` varchar(10), `year` varchar(4));

  INSERT INTO budget
      ( `budget_id`,`subkat_id`,`budgetedAmmount`,`year`)
  VALUES
      ('1','1',"111",'2017'),
      ('2','2',"222",'2017'),
      ('3','3',"333",'2017'),
      ('4','4',"444",'2017'),
      ('1','1',"111",'2016'),
      ('2','2',"222",'2016'),
      ('3','3',"333",'2016'),
      ('4','4',"444",'2016');

Query 1 : 查询1

SELECT
      IFNULL(Year, 'All')       AS Year
    , IFNULL(Month, 'All')      AS Month
    , IFNULL(Kategori,'All')    AS Kategori
    , IFNULL(Subkategori,'All') AS Subkategori
    , IFNULL(Belopp,0)          AS Belopp
    , IFNULL(Budget,0)          AS Budget
FROM (
      SELECT
            y.year                         AS year
          , m.n                            AS month
          , kategori.kat_namn              AS kategori
          , subkategori.subkat_namn                  AS subkategori
          , SUM(IFNULL(transaktioner.belopp,0))      AS belopp
          , SUM(IFNULL(b.budgetedAmmount,0))         AS budget
      FROM subkategori
      INNER JOIN kategori ON subkategori.kat_id = kategori.kat_id
      CROSS JOIN (
            SELECT 2017 year 
            ) y
      CROSS JOIN (
            SELECT 1 n union all SELECT 2 n union all SELECT 3 n union all SELECT 4 n union all 
            SELECT 5 n union all SELECT 6 n union all SELECT 7 n union all SELECT 8 n union all 
            SELECT 9 n union all SELECT 10  union all SELECT 11  union all SELECT 12
            ) m
      LEFT JOIN transaktioner ON subkategori.subkat_id = transaktioner.subkat_id
            AND y.year = YEAR(transaktioner.datum)
            AND m.n = MONTH(transaktioner.datum)
      LEFT JOIN (
                SELECT subkat_id, Year, budgetedAmmount/12 as budgetedAmmount
                FROM budget
                ) b ON subkategori.subkat_id = b.subkat_id
                    AND y.year = b.year
      GROUP BY
            y.year 
          , m.n
          , kategori.kat_namn 
          , subkategori.subkat_namn 
      WITH ROLLUP
      ) d
ORDER BY
      IFNULL(Year, 9999)
    , IFNULL(Month, 13)
    , IFNULL(Kategori,'zzzzzzzzz') 
    , IFNULL(Subkategori,'zzzzzzzzzzz')
;

Results : 结果

| Year | Month | Kategori | Subkategori | Belopp | Budget |
|------|-------|----------|-------------|--------|--------|
| 2017 |     1 |     Kat1 |     subKat1 |   1000 |   9.25 |
| 2017 |     1 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     1 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     1 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     1 |     Kat1 |         All |   1000 |   92.5 |
| 2017 |     1 |      All |         All |   1000 |   92.5 |
| 2017 |     2 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     2 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     2 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     2 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     2 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     2 |      All |         All |      0 |   92.5 |
| 2017 |     3 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     3 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     3 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     3 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     3 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     3 |      All |         All |      0 |   92.5 |
| 2017 |     4 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     4 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     4 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     4 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     4 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     4 |      All |         All |      0 |   92.5 |
| 2017 |     5 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     5 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     5 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     5 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     5 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     5 |      All |         All |      0 |   92.5 |
| 2017 |     6 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     6 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     6 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     6 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     6 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     6 |      All |         All |      0 |   92.5 |
| 2017 |     7 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     7 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     7 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     7 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     7 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     7 |      All |         All |      0 |   92.5 |
| 2017 |     8 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     8 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     8 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     8 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     8 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     8 |      All |         All |      0 |   92.5 |
| 2017 |     9 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |     9 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |     9 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |     9 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |     9 |     Kat1 |         All |      0 |   92.5 |
| 2017 |     9 |      All |         All |      0 |   92.5 |
| 2017 |    10 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |    10 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |    10 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |    10 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |    10 |     Kat1 |         All |      0 |   92.5 |
| 2017 |    10 |      All |         All |      0 |   92.5 |
| 2017 |    11 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |    11 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |    11 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |    11 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |    11 |     Kat1 |         All |      0 |   92.5 |
| 2017 |    11 |      All |         All |      0 |   92.5 |
| 2017 |    12 |     Kat1 |     subKat1 |      0 |   9.25 |
| 2017 |    12 |     Kat1 |     subKat2 |      0 |   18.5 |
| 2017 |    12 |     Kat1 |     subKat3 |      0 |  27.75 |
| 2017 |    12 |     Kat1 |     subKat4 |      0 |     37 |
| 2017 |    12 |     Kat1 |         All |      0 |   92.5 |
| 2017 |    12 |      All |         All |      0 |   92.5 |
| 2017 |   All |      All |         All |   1000 |   1110 |
|  All |   All |      All |         All |   1000 |   1110 |

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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