如果当前行值为NULL

时间:2015-10-12 08:54:01

标签: mysql

我有一张钱包交易表。使用此表中的数据,我需要获得每个月中每个钱包的余额信息。 月份列表必须从同一个表的交易日期定义。因此,如果第一笔交易是在2012-01-14 23:44:12,最后一个是在当月(2015-10),我应该有这样的年月列表:

2012-01
2012-02
2012-03
...
2015-10

要获取可用的年 - 月组合列表,我使用下一个子查询:

SELECT DISTINCT DATE_FORMAT( `created` , '%Y-%m' ) AS `d` FROM `transactions`

它应该足够好了,因为我确信每个月至少有一笔交易(不是每个钱包都是共同的)。

我需要实现的目标 - 为每月的可用月份+ wallet_id +最大余额制作一个包含组合的列表。如果在某个特定月份没有钱包交易,我需要从上个月拿出余额。因此结果数据必须如下所示:

Month   | Wallet | Balance
2012-01 | 234    | 111.10
2012-02 | 234    | 45.29
2012-03 | 234    | 45.29 (no transaction in 2012-03, so take value from prev month)
2012-04 | 234    | 45.29 (no transaction in 2012-04, so take value from prev month)
2012-05 | 234    | 45.29 (no transaction in 2012-05, so take value from prev month)
2012-06 | 234    | 45.29 (no transaction in 2012-06, so take value from prev month)
2012-07 | 234    | 14.32 (new transaction in 2012-07, so calculate new value)

我需要为每个钱包ID。

具有交易的表具有下一个结构:

CREATE TABLE IF NOT EXISTS `transactions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `wallet_id` int(11) NOT NULL,
  `credit` decimal(7,2) NOT NULL DEFAULT '0.00',
  `bonus` decimal(7,2) NOT NULL DEFAULT '0.00',
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `wallet_id` (`wallet_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

到目前为止,即使获得所有可用年月+钱包ID +余额的列表,我也遇到问题,如果本月没有此钱包的交易,则余额为NULL。所以现在我想要至少有这样的列表(与上面的表格相比,我最终需要得到):

Month   | Wallet | Balance
2012-01 | 234    | 111.10
2012-02 | 234    | 45.29
2012-03 | 234    | NULL
2012-04 | 234    | NULL
2012-05 | 234    | NULL
2012-06 | 234    | NULL
2012-07 | 234    | 14.32

如果我有这个,下一步是从前一行获取值,如果当前有NULL余额。

到目前为止,我的查询看起来像这样:

SELECT dates.*, `t`.*
FROM (
    SELECT DISTINCT DATE_FORMAT( `created` , '%Y-%m' ) AS `d`
    FROM `transactions`
) AS `dates`
LEFT JOIN (
    SELECT `wallet_id` ,
            MAX( `credit` + `bonus` ) AS `balance` ,
            DATE_FORMAT( `created` , '%Y-%m' ) AS `date`
    FROM `transactions`
    GROUP BY `wallet_id` , `date`
) AS `t` ON ( `t`.`date` = `dates`.`d` )
ORDER BY `t`.`wallet_id`, `t`.`date`

但现在所有月份都没有钱包的交易错过了结果。所以我有这样的事情:

Month   | Wallet | Balance
2012-01 | 234    | 111.10
2012-02 | 234    | 45.29
2012-07 | 234    | 14.32

如何在我需要的视图中修改查询以获取列表?

更好的是,如何实现我的最终目标,将所有月份和NULL余额替换为上一行的值?

重点 - 我将使用查询结果作为一种视图(实际上是BI工具中的派生表)。

1 个答案:

答案 0 :(得分:0)

生成序列

据我所知,你需要mysql中的行生成器,但是有一个。见How do I make a row generator in MySQL?

尝试'generate_series'程序: generate many rows with mysql

搜索现有数据库数月序列

作为替代解决方案,我会在DB中找到一种存储每个月值的方法(因此您不必生成数月序列)。如果你没有很多插入,你可以做一个触发器,检查是否有前几个月的数据,如果为空则创建空事务