Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL查询,根据可变持续时间条目每月生成输出_Mysql_Sql - Fatal编程技术网

MySQL查询,根据可变持续时间条目每月生成输出

MySQL查询,根据可变持续时间条目每月生成输出,mysql,sql,Mysql,Sql,好的,我有一个表,其中包含与日期和持续时间相关的付款 示例数据: purchase_id date_purchased user_id duration (in months) amount_income 1 2013-12-28 00:00:00 1 2 £15 2 2014-01-04 00:00:00 2 1

好的,我有一个表,其中包含与日期和持续时间相关的付款

示例数据:

purchase_id  date_purchased         user_id   duration (in months)   amount_income
1            2013-12-28 00:00:00    1         2                      £15
2            2014-01-04 00:00:00    2         1                      £10
3            2014-02-04 00:00:00    3         6                      £40
*因此,用户支付的时间越长,他们每月支付的费用就越少

我想显示的是基于此表的每月总收入。因此,2个月内支付15英镑意味着2个月内每月收入7.50英镑

样本输出:

Month       Amount
2013-12     £7.50
2014-01     £17.50
2014-02     £6.66
2014-03     £6.66
2014-04     £6.66
2014-05     £6.66
2014-06     £6.66
2014-07     £6.66
此输出与上面的示例输入相对应。希望它能澄清每月收入的细目


你知道如何在查询中做到这一点吗?

假设你可以轻松地从datetime中提取月份,因此真正的问题是聚合逻辑,你可以创建一个数字表

下面是一个简单的示例,展示了该模式

那么:

SELECT a.my_date, a.income, IFNULL(SUM(DISTINCT(a.income)) + sum( b.income ), a.income) as roll_up
FROM (
SELECT purchase_id, DATE_FORMAT( date_purchased, '%y-%m') AS my_date, SUM( amount_income / duration ) AS "income"
FROM incomes
GROUP BY my_date
) AS a
LEFT OUTER JOIN (
SELECT purchase_id, DATE_FORMAT( date_purchased, '%y-%m') AS my_date, SUM(amount_income / duration ) AS "income"
FROM incomes
GROUP BY my_date
) AS b ON ( a.purchase_id > b.purchase_id )
按a.purchase\u id分组

在一次拍摄中完成这一点有点棘手,可能会有所改进,但这会产生以下结果:

my_date  income     roll_up
13-12    8.5000     8.5000
14-01   10.0000     18.5000
14-02   16.6667     35.1667
我的数据集是:

1   2013-12-28 00:00:00     1   2   15
2   2014-01-04 00:00:00     2   1   10
3   2014-02-04 00:00:00     3   6   40
4   2013-12-29 00:00:00     4   1   1
5   2014-02-28 00:00:00     5   2   20

像卡尔一样,我很确定这里需要某种数字表。我个人喜欢,它定义了一个视图,其中几个视图可以生成数字,而不必实际存储一个充满数字的表。无论您使用的是表还是视图,当您从中进行选择时,其外观如下所示:

N -- 0 1. 2. 3. … 使用它,您可以构造如下查询:

选择 purchases.purchase\u id, 购买。购买日期, 购买时间, -生成器_16是我们的数字表 发电机_16.n, -下面,我们按照以下方式计算年份和月份: -1获取一年中的第一天,例如,如果购买日期为2012-12-28, -这给了我们2012-01-01。 -2获取月数,例如2012-12-28的12个月,并添加该月数 -到一年的第一天,这给了我们一年的第一天 -月份,2012年12月1日。 -3加n个月,其中n是我们从数字表中得到的数字, -从0开始。 日期加-3 日期添加-2 MAKEDATE YEARpurchases.date_purchased,1,-1 购买时间间隔月购买日期-1个月-2 , 间隔发生器\u 16.n月-3 作为元旦, 采购.金额\收入/采购.持续时间作为金额 从购买 -下面的连接表示如果'purchases.duration'为3,则得到三行 -在'n'列中有0、1和2,我们将其用作日期数 -在上面加上3。 连接生成器_16 在生成器_16.n上,介于0和0之间。持续时间-1 按采购订单。采购id,年份\u-mon; 这给了我们这样一个结果:

采购\u id日期\u采购期限n年\u月金额 ------ ------- ---- - ------ --- 1 2013-12-28 … 2 0 2013-12-01 … 7.5 1 2013-12-28 … 2 1 2014-01-01 … 7.5 2 2014-01-04 … 1 0 2014-01-01 … 10 3 2014-02-04 … 6 0 2014-02-01 … 6.6667 3 2014-02-04 … 6 1 2014-03-01 … 6.6667 3 2014-02-04 … 6 2 2014-04-01 … 6.6667 3 2014-02-04 … 6 3 2014-05-01 … 6.6667 3 2014-02-04 … 6 4 2014-06-01 … 6.6667 3 2014-02-04 … 6 5 2014-07-01 … 6.6667 我插入了空行来分隔购买id组,这样您就可以看到组中每个项目的n是如何从0增加到持续时间-1的。如您所见,year_mon等于购买日期的第一天之后的n个月加上n个月,amount等于amount_income/duration

我们几乎完成了,但正如你们所看到的,周一有重复:2014-01-01显示了两次。这是一个好消息,因为我们可以使用GROUP BY对该列进行分组,然后使用SUMMOUNT得到当月的总数:

选择 添加日期 添加日期 MAKEDATE YEARpurchases.date_purchased,1, 购买日期间隔月-1个月 , 间隔发生器\u 16.n月 作为元旦, SUMpurchases.amount_收入/购买额.duration总计 从购买 连接生成器_16 在生成器_16.n上,介于0和0之间。持续时间-1 一年一组 每年(一月)订购;; 此查询与前一个月之间的唯一区别是,我们按年度、月份和金额、收入/持续时间进行分组,以获得该月的总计,结果如下:

一年一次总计 ------ --- 2013-12-01 … 7.5 2014-01-01 … 17.5 2014-02-01 … 6.6667 2014-03-01 … 6.6667 2014-04-01 … 6.6667 2014-05-01 … 6.6667 2014-06-01 … 6.6667 2014-07-01 … 6.6667
…当然,您可以使用DATE_格式和CAST或ROUND来获得格式良好的日期和金额,或者您也可以在前端代码中这样做。

和函数。这是MySQL还是SQL Server?MySQL抱歉,问题已编辑。请回答
请特别注意MySQL的非常有用的特性,问题中的示例输出是随机的-我只是为了澄清我需要的输出格式。
1   2013-12-28 00:00:00     1   2   15
2   2014-01-04 00:00:00     2   1   10
3   2014-02-04 00:00:00     3   6   40
4   2013-12-29 00:00:00     4   1   1
5   2014-02-28 00:00:00     5   2   20