[英]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 这可能会帮助您找到答案
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
Run that partial query in MySQL directly, if you get a result 如果得到结果,则直接在MySQL中运行该部分查询
run the complete query in MySQL, if you get a result 如果得到结果,请在MySQL中运行完整的查询
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.
我希望从这个例子中您可以使其适应您的特定需求。
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')
;
| 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.