英文:
Group Report With Header and Detail?
问题
我有一个名为“transactions”的表,其中包含以下详细信息
id | dt_trans | category | description | amount |
---|---|---|---|---|
1 | 2022-08-05 | Expense | Food | 60.00 |
2 | 2022-08-05 | Travel | Petrol | 20.00 |
2 | 2022-08-08 | Travel | Petrol | 20.00 |
然后我想根据以下报告创建报告
dt_trans | category | description | amount | |
---|---|---|---|---|
Expense | ||||
1 | 2022-08-05 | Expense | Food | 60.00 |
Total | 60.00 | |||
Travel | ||||
1 | 2022-08-05 | Travel | Petrol | 20.00 |
2 | 2022-08-08 | Travel | Petrol | 20.00 |
Total | 40.00 |
通常情况下,我会基于报告创建一个临时表,并基于2个查询添加行。以下是逻辑
循环 // 查询1 检索所有类别
查询2 根据类别检索所有详细信息
循环结束 查询1
是否有更简单的方法来创建此报告?
查询:
如果存在,则删除表`transaction`;
创建表`transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cashaccount_id` int(11) DEFAULT NULL,
`dt_trans` date DEFAULT NULL,
`category` varchar(200) DEFAULT NULL,
`description` varchar(500) DEFAULT NULL,
`type` tinyint(4) DEFAULT NULL COMMENT '0 income 1 expense',
`amount` float(10,2) DEFAULT 0.00,
`dt_created` datetime DEFAULT NULL,
`uid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
向表`transaction`中插入值 (`id`, `cashaccount_id`, `dt_trans`, `category`, `description`, `type`, `amount`, `dt_created`, `uid`) VALUES
(115, 1, '2021-10-10', 'Expense', 'Food', 1, 60.00, '2021-10-10 17:06:36', 1),
(121, 1, '2021-10-15', 'Travel', 'Petrol', 1, 20.00, '2021-10-15 01:01:15', 1),
(123, 1, '2021-10-05', 'Travel', 'Petrol', 0, 20.00, '2021-10-15 09:11:28', 1)
英文:
I have table transactions with below details
id | dt_trans | category | description | amount |
---|---|---|---|---|
1 | 2022-08-05 | Expense | Food | 60.00 |
2 | 2022-08-05 | Travel | Petrol | 20.00 |
2 | 2022-08-08 | Travel | Petrol | 20.00 |
then I want to create report based on below report
dt_trans | category | description | amount | |
---|---|---|---|---|
Expense | ||||
1 | 2022-08-05 | Expense | Food | 60.00 |
Total | 60.00 | |||
Travel | ||||
1 | 2022-08-05 | Travel | Petrol | 20.00 |
2 | 2022-08-08 | Travel | Petrol | 20.00 |
Total | 40.00 |
Usually I will create a temporary table based on the report and add the row based on 2 queries.
Here's the logic
Loop // query1 retrieve all the category
query2 retrieve all the details based on category
end of loop query1
Is there a more simple way to create this report?
query:
DROP TABLE IF EXISTS `transaction`;
CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cashaccount_id` int(11) DEFAULT NULL,
`dt_trans` date DEFAULT NULL,
`category` varchar(200) DEFAULT NULL,
`description` varchar(500) DEFAULT NULL,
`type` tinyint(4) DEFAULT NULL COMMENT '0 income 1 expense',
`amount` float(10,2) DEFAULT 0.00,
`dt_created` datetime DEFAULT NULL,
`uid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
INSERT INTO `transaction` (`id`, `cashaccount_id`, `dt_trans`, `category`, `description`, `type`, `amount`, `dt_created`, `uid`) VALUES
(115, 1, '2021-10-10', 'Expense', 'Food', 1, 60.00, '2021-10-10 17:06:36', 1),
(121, 1, '2021-10-15', 'Travel', 'Petrol', 1, 20.00, '2021-10-15 01:01:15', 1),
(123, 1, '2021-10-05', 'Travel', 'Petrol', 0, 20.00, '2021-10-15 09:11:28', 1)
答案1
得分: 1
尝试使用以下特定顺序将三个选择语句合并:
获取所有用户的报告:
with t as
(
select id, dt_trans, category, description, amount, uid,
dense_rank() over (order by uid, category) as ord1, 2 as ord2
from transaction
union all
select distinct category, '', '', '', '', uid,
dense_rank() over (order by uid, category) as ord1,
1 as ord2
from transaction
union all
select '', '', '', 'Total',
sum(amount), uid,
dense_rank() over (order by uid, category) as ord1,
3 as ord2
from transaction
group by category, uid
)
select uid, id, dt_trans, category, description, amount
from t
order by uid, ord1, ord2
获取单个用户的报告:
with t as
(
select id, dt_trans, category, description, amount,
dense_rank() over (order by category) as ord1, 2 as ord2
from transaction where uid = 1
union all
select distinct category, '', '', '',
dense_rank() over (order by category) as ord1,
1 as ord2
from transaction where uid = 1
union all
select '', '', '', 'Total',
sum(amount),
dense_rank() over (order by category) as ord1,
3 as ord2
from transaction where uid = 1
group by category
)
select id, dt_trans, category, description, amount
from t
order by ord1, ord2
但最好在SQL服务器之外执行此类格式化报告。
英文:
Try to union three select statements with a specific order for each one as the following:
To get the report for all users:
with t as
(
select id, dt_trans, category, description, amount, uid,
dense_rank() over (order by uid, category) as ord1, 2 as ord2
from transaction
union all
select distinct category, '', '', '', '', uid,
dense_rank() over (order by uid, category) as ord1,
1 as ord2
from transaction
union all
select '', '', '', 'Total',
sum(amount), uid,
dense_rank() over (order by uid, category) as ord1,
3 as ord2
from transaction
group by category, uid
)
select uid, id, dt_trans, category, description, amount
from t
order by uid, ord1, ord2
To get the report for a single user:
with t as
(
select id, dt_trans, category, description, amount,
dense_rank() over (order by category) as ord1, 2 as ord2
from transaction where uid = 1
union all
select distinct category, '', '', '', '',
dense_rank() over (order by category) as ord1,
1 as ord2
from transaction where uid = 1
union all
select '', '', '', 'Total',
sum(amount),
dense_rank() over (order by category) as ord1,
3 as ord2
from transaction where uid = 1
group by category
)
select id, dt_trans, category, description, amount
from t
order by ord1, ord2
But it would be better to perform this kind of formatting reports outside the SQL server.
答案2
得分: 1
尝试使用 ROLLUP。示例:
select category head,rn, max(dt_trans)dt_trans,category,max(description)description,sum(amount) amount
from(
select *
,row_number()over(partition by category order by category desc,dt_trans) rn
from transaction
) t
group by category ,rn with rollup
结果。rn 中有空值 - 按类别汇总,head 和 rn 中都有空值 - 汇总报告。
|head| rn | dt_trans | category | description | amount |
|:----|-:--|:----------|:---------|:------------|-------:|
|支出 | 1 | 2021-10-10 | 支出 | 食物 | 60.00 |
|支出 |null| 2021-10-10 | 支出 | 食物 | 60.00 |
|旅行 | 1 | 2021-10-05 | 旅行 | 汽油 | 20.00 |
|旅行 | 2 | 2021-10-15 | 旅行 | 汽油 | 20.00 |
|旅行 |null| 2021-10-15 | 旅行 | 汽油 | 40.00 |
|null |null| 2021-10-15 |null | 汽油 |100.00 |
英文:
Try use ROLLUP. Example
select category head,rn, max(dt_trans)dt_trans,category,max(description)description,sum(amount) amount
from(
select *
,row_number()over(partition by category order by category desc,dt_trans) rn
from transaction
) t
group by category ,rn with rollup
Result. There null in rn - totals by category, null in both head and rn - report totals.
head | rn | dt_trans | category | description | amount |
---|---|---|---|---|---|
Expense | 1 | 2021-10-10 | Expense | Food | 60.00 |
Expense | null | 2021-10-10 | Expense | Food | 60.00 |
Travel | 1 | 2021-10-05 | Travel | Petrol | 20.00 |
Travel | 2 | 2021-10-15 | Travel | Petrol | 20.00 |
Travel | null | 2021-10-15 | Travel | Petrol | 40.00 |
null | null | 2021-10-15 | null | Petrol | 100.00 |
答案3
得分: 0
以下是翻译好的部分:
你可以尝试在编程方面循环,但这里是一个简单的mysql查询
SELECT
s.*
FROM
transaction s
CROSS JOIN
(SELECT
category
FROM
transaction) AS t
GROUP BY s.id
英文:
You may try to loop on programming side but here is a simple mysql query
SELECT
s.*
FROM
transaction s
CROSS JOIN
(SELECT
category
FROM
transaction) AS t
GROUP BY s.id
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论