如果下个月没有数据,则获取上个月的数据

时间:2018-10-16 15:48:16

标签: mysql join cross-join

如果下个月没有数据,我想获取上个月的数据。 假设数据是:

stock_item month stock
pepsi      4     100
pepsi      5     120
pepsi      9     80
coca cola  4     90
coca cola  6     100
coca cola  8     120

输出应为:

stock_item month stock
pepsi      4     100
pepsi      5     120
pepsi      6     120
pepsi      7     120
pepsi      8     120
pepsi      9     80
pepsi      10    80
coca cola  4     90
coca cola  5     90
coca cola  6     100
coca cola  7     100
coca cola  8     120
coca cola  9     120
coca cola  10    120

月在4到10之间,因为印度会计年度从4月开始,而本月是10月,所以是10。

1 个答案:

答案 0 :(得分:0)

这里有部分答案,如何针对一只股票完成此操作。

首先,为所需的月份创建一个表并填充它。这给了我们一些迭代的机会。

create table stock_months (
    int month_num not null
);
insert into stock_months values (4), (5), (6), (7), (8), (9), (10);

现在,我们可以从此表中选择月份,并用stocksleft outer join来选择所有月份。

select stock_item, month_num, stock
from stock_months sm
left outer join stocks s
    on sm.month_num = s.month and s.stock_item = 'pepsi'

+------------+-----------+-------+
| stock_item | month_num | stock |
+------------+-----------+-------+
| pepsi      |         4 |   100 |
| pepsi      |         5 |   120 |
| pepsi      |         9 |    80 |
| NULL       |         6 |  NULL |
| NULL       |         7 |  NULL |
| NULL       |         8 |  NULL |
| NULL       |        10 |  NULL |
+------------+-----------+-------+

我们可以使用变量来记住上一行的值。

select
    case when stock_item is null then
        @stock_item
    else
        @stock_item := stock_item
    end as stock_item,
    month_num,
    case when stock is null then
        @stock
    else 
        @stock := stock
    end as stock
from stock_months sm
left outer join stocks s
    on sm.month_num = s.month and s.stock_item = 'pepsi'
order by month_num;

+------------+-----------+-------+
| stock_item | month_num | stock |
+------------+-----------+-------+
| pepsi      |         4 |   100 |
| pepsi      |         5 |   120 |
| pepsi      |         6 |    80 |
| pepsi      |         7 |    80 |
| pepsi      |         8 |    80 |
| pepsi      |         9 |    80 |
| pepsi      |        10 |    80 |
+------------+-----------+-------+

为什么没有用?因为select以其喜欢的顺序遍历联接的结果。然后排序。在这种情况下,它首先使用stock_item行。

我们需要首先对连接的行进行排序。我们可以通过从已经按顺序选择的子选择中进行选择。

select
    case when stock_item is null then
        @stock_item
    else
        @stock_item := stock_item
    end as stock_item,
    month_num,
    case when stock is null then
        @stock
    else 
        @stock := stock
    end as stock
from (
    select stock_item, month_num, stock
    from stock_months sm
    left outer join stocks s
        on sm.month_num = s.month and s.stock_item = 'pepsi'
    order by month_num
) stocks;

+------------+-----------+-------+
| stock_item | month_num | stock |
+------------+-----------+-------+
| pepsi      |         4 |   100 |
| pepsi      |         5 |   120 |
| pepsi      |         6 |   120 |
| pepsi      |         7 |   120 |
| pepsi      |         8 |   120 |
| pepsi      |         9 |    80 |
| pepsi      |        10 |    80 |
+------------+-----------+-------+

我不确定如何从这里转到所有库存物品。