我有一个MySQLtransfers
表,结构如下:
CREATE TABLE `transfers` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`id_account_destination` bigint(20) unsigned NOT NULL,
`id_account_origin` bigint(20) unsigned NOT NULL,
`amount` decimal(10, 2) signed NOT NULL DEFAULT 0,
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `id_account_destination` (`id_account_destination`),
KEY `id_account_origin` (`id_account_origin`),
KEY `created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这张表显然存储了转账。记录了 * 转账**金额 * 和涉及的两个 * 账户 *:origin 和 destination
我需要的是创建一个SELECT
语句,它从一个时期(通过created_at
过滤)获取所有给定的 * 转账 *,并向我显示所有当前账户在该部分中的收入和结果。类似于:
+------------+---------------+-----------------|
| id_account | income_amount | outcome_ammount |
+------------+---------------+-----------------|
| 19 | 27690.87 | 57204.80 |
| 112 | 1000.00 | 2349.00 |
| 1011 | 575877.56 | 17454.50 |
| 17 | 135002.61 | 204.30 |
+------------+---------------+-----------------|
这里的困难在于,id_account
列将从任何传输中获取id_account_origin
或id_account_destination
,并通过其余传输找到其所有其他出现。如果账户在“原点”位置,转账的 * 金额 * 将被添加到outcome_ammount
列;但如果在“目的地”位置找到该帐户,则应将转账的 * 金额 * 添加到income_ammount
列。
因此,输出表与传输表完全不同,尽管所有需要的信息都已经存在。
到目前为止,我只通过一种方式获得了这些信息:
SELECT
id_account_origin,
SUM(t.amount) AS outcome_amount
FROM transfers t
GROUP BY t.id_account_origin;
它返回:
+-------------------+----------------+
| id_account_origin | outcome_amount |
+-------------------+----------------+
| 10009 | 2761390.87 |
| 10012 | 1000.00 |
| 10011 | 575877.56 |
| 10007 | 135002.61 |
+-------------------+----------------+
并且比上面预期的跨列容易得多。
2条答案
按热度按时间qaxu7uf21#
为
id_account_destination
编写另一个查询。然后将它们与UNION
组合以取消透视。2w2cym1i2#
一种方法是对数据进行反透视,然后进行聚合。
在最近的MySQL版本中,我们可以使用横向连接,这避免了使用
union all
扫描表两次:参考:MySQL - How to unpivot columns to rows?
这里是a small demo。
样本数据:
| 身份证|id_account_destination|id_account_origin|数量|创建于|
| --------------|--------------|--------------|--------------|--------------|
| 1|1|二|一百|2023-05-04 19:59:37|
| 二|1|三|50块|2023-05-04 19:59:37|
| 三|四个|1|三十|2023-05-04 19:59:37|
结果:
| id_account|收入额|产出量|
| --------------|--------------|--------------|
| 1|一百五十|三十|
| 二|零点|一百|
| 三|零点|50块|
| 四个|三十|零点|