将行插入MySQL数据库

时间:2014-07-03 19:30:39

标签: mysql sql

我的数据形成如下:

+----------+-------+-------+
| DAY      | VALUE | Name  |
+----------+-------+-------+
| 01/01/14 |  1030 |  BOB
| 01/02/14 |  1020 |  BOB
| 01/03/14 |  1080 |  BOB
| 01/04/14 |  1090 |  BOB
| 01/05/14 |  1040 |  BOB
| 01/08/14 |  1030 |  BOB
| 01/11/14 |  4030 |  BOB
| 01/12/14 |  5000 |  BOB
| 01/13/14 |  6000 |  BOB
| 01/14/14 |  1096 |  BOB
| 01/14/14 |  1200 |  MIKE
| 01/15/14 |  1040 |  MIKE
| 01/16/14 |  1600 |  MIKE
| 01/17/14 |  1070 |  MIKE
| 01/18/14 |  1340 |  MIKE
| 01/19/14 |  1060 |  MIKE
| 01/01/14 |  6000 |  JANE
| 01/02/14 |  1700 |  JANE
| 01/03/14 |  1070 |  JANE
| 01/04/14 |  8000 |  JANE
+----------+-------+------+

对于每个名称,2014年1月1日至2014年1月1日(1个月)之间的日期需要有一行。正如你所看到的,Bob,Mike和Jane(虽然在我的真实数据库中有数千个名字)都是在这个时间段之间缺少日期。我想以某种方式通过插值插入缺少的行。例如Bob缺少2014年6月1日和01/07/14。我希望通过添加这两个日期进行插值,然后将值作为两个字段之间的平均值,这样这两个缺失的字段都将具有值((1040 + 1030)/ 2)= 1035.如果没有之前的数据就像MIKE一样(从2014年1月14日开始)我希望所有新行现在都具有01/14/14值。我尝试了各种不同的技术,例如使用coalesce命令,游标,但无法使其工作。此外,我没有设置这些EXACT值,如果有某种数学库可以插值我也会对此开放。感谢。

1 个答案:

答案 0 :(得分:1)

您有两个问题,即生成行并插值。您可以使用此SQL生成行:

select d.day, n.name, t.value
from (select distinct name from table t) n cross join
     (select distinct day from table t) d left outer join
     table t
     on t.name = n.name and t.day = d.day;

进行插值很麻烦。您可以使用变量和多重排序来完成此操作。这是逻辑:

select day, name, value, prev_value,
       @value as next_value,
       @value := if(@name = name and value is not null, value, @value),
       @name := name
from (select d.day, n.name, t.value,
             @value as prev_value,
             @value := if(@name = name and value is not null, value, @value),
             @name := name
      from (select distinct name from table t) n cross join
           (select distinct day from table t) d left outer join
           table t
           on t.name = n.name and t.day = d.day cross join
           (select @name := '', @value := NULL) vars
      order by n.name, d.day
     ) t cross join
     (select @name := '', @value := NULL) vars
order by n.name, d.day desc;

这可能对您有用,但它依赖于MySQL在每个select中按顺序评估表达式(用于变量赋值)。您可以使语法更复杂以解决此问题,但这会隐藏逻辑。您现在可以实现所需的逻辑:

select day, name,
       (case when value is not null then value
             when prev_value is not null and next_value is not null
             then (prev_value + next_value) / 2
             when prev_value is null then next_value
             else prev_value
        end) as value
from (<previous query here>) t;