【问题标题】:MySQL - Display data accurately by fiscal_yearMySQL - 按财政年准确显示数据
【发布时间】:2017-01-22 11:52:04
【问题描述】:

寻求帮助。这是我的架构

CREATE TABLE `net_savings` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `account_id` int(11) NOT NULL,
  `monthname` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
  `fiscal_year` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
  `amount` decimal(30,2) DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `net_savings_id_unique` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

我的数据:

    INSERT INTO `net_savings` VALUES  
(10,1,'January','2016',-1291.47,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(11,1,'February','2017',389296.02,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(12,1,'March','2018',216143.70,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(13,2,'April','2019',53840.00,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(14,2,'May','2017',1669693.00,'0000-00-00 00:00:00','2016-08-30 04:00:00'),
(15,2,'June','2018',1980328.00,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(16,2,'July','2019',2428559.00,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(17,3,'August','2016',963.32,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(18,3,'September','2017',3960.93,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(19,4,'October','2016',-261.74,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(20,4,'November','2017',24160.80,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(21,4,'December','2018',24160.80,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(22,4,'January','2019',8053.60,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(23,5,'February','2016',8846.54,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(24,5,'March','2017',41141.34,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(25,5,'April','2018',41141.34,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(26,5,'May','2019',41141.34,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(27,5,'June','2020',27427.56,'2016-08-30 04:00:00','2016-08-30 04:00:00'),
(31,1,'March','2016',100.00,'2016-09-14 11:33:48','2016-09-14 11:33:48');

这是我的存储过程:

CREATE DEFINER=`root`@`localhost` PROCEDURE `financial_forecast_yearly`()
BEGIN
SET group_concat_max_len=2048;
SET @sql = NULL;

    SELECT GROUP_CONCAT(DISTINCT
            CONCAT(
                'MAX(IF(n.fiscal_year = ''',
                n.fiscal_year, ''', n.amount, NULL))AS ',
                    CONCAT("'","FY_",n.fiscal_year,"'"))) 
    INTO @sql
    FROM net_savings n join accounts a
    ON n.account_id = a.id;

    SET @sql = CONCAT('SELECT a.id,
                            a.account, 
                            a.region, 
                            SUM(n.amount) as total_net_savings,'
                            ,@sql,
                            'FROM net_savings n  join accounts a
                            on  n.account_id = a.id
                            GROUP BY a.account, n.account_id 
                            ORDER BY a.id');

PREPARE statement FROM @sql;
EXECUTE statement;
DEALLOCATE PREPARE statement;
END

输出如下:

但是,显示的数据并不准确。例如,我在 2016 年 3 月的某个地方输入了相同的金额,总数未汇总到 FY2016 列。

【问题讨论】:

    标签: mysql database pivot-table aggregate-functions


    【解决方案1】:

    那个存储过程复杂难解!

    你正在尝试做两件事:

    1. 您正在尝试按会计年度汇总。
    2. 您正在尝试调整结果。

    最好分两步处理。

    第一:(http://sqlfiddle.com/#!9/26179/3/0)

    SELECT SUM(amount) amount,
           account_id, fiscal_year
      FROM net_savings 
     GROUP BY account_id, fiscal_year WITH ROLLUP
    

    其次,旋转是 MySQL 的一大痛点。

    你可能需要这样的东西:

    SELECT account_id,
           SUM(CASE WHEN fiscal_year IS NULL THEN amount ELSE 0 END) total,
           SUM(CASE WHEN fiscal_year = 2016 THEN amount ELSE 0 END) fy2016,
           SUM(CASE WHEN fiscal_year = 2017 THEN amount ELSE 0 END) fy2017,
           SUM(CASE WHEN fiscal_year = 2018 THEN amount ELSE 0 END) fy2018,
           SUM(CASE WHEN fiscal_year = 2019 THEN amount ELSE 0 END) fy2019,
           SUM(CASE WHEN fiscal_year = 2020 THEN amount ELSE 0 END) fy2020
     FROM (
                   SELECT SUM(amount) amount,
                         account_id, fiscal_year
                    FROM net_savings 
                GROUP BY account_id, fiscal_year WITH ROLLUP
          ) summary
    WHERE account_id IS NOT NULL
    GROUP BY account_id 
    

    一旦您知道这是您的目标语句,您就可以编写存储过程来创建它并准备它。

    【讨论】:

    • 谢谢!如果我有一个静态财政年度,这很有效,但如果我添加 2021 财政年度,它就不会出现。我旋转的原因是让它尽可能动态。
    • 没错。其他一些 DBMS 提供旋转命令,但不提供 MySQL。例如,PostgreSQL:postgresql.org/docs/9.1/static/tablefunc.html
    • 尝试合并我的帐户表,但帐户字段无法识别。
    猜你喜欢
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多