在此之前,这里是数据库的简化schema
(带虚拟记录):
ITEMLIST
ItemID ItemName DateAcquired Cost MonthlyDep CurrentValue
================================================================================
1 Stuff Toy 2011-12-25 100.00 10.00 100.00
2 Mouse 2011-12-23 250.00 50.00 200.00
3 Keyboard 2011-12-17 250.00 30.00 190.00
4 Umbrella 2011-12-28 150.00 20.00 110.00
5 Aircon 2011-12-29 950.00 25.00 925.00
DepreciationTransaction
ItemID DateOfDep MonthlyDep
======================================
2 2012-01-31 250.00
3 2012-01-31 30.00
4 2012-01-31 20.00
5 2012-01-31 25.00
3 2012-02-29 30.00
4 2012-02-29 20.00
我需要你的建议来帮助我解决这个问题。基本上我正在创建某个LGU的折旧监控系统。当前数据库的问题在于它缺少特定折旧日期的某些记录,例如:
缺乏记录(这不是数据库中的表格)
ItemID LackingDate
============================
1 2012-01-31
1 2012-02-29
2 2012-02-29
5 2012-02-29
由于缺少记录,我无法生成MARCH
月份的折旧报告。我知道如何在DepreciationTransaction
上插入缺失的记录?
到目前为止我做了什么? 无。但是计算新折旧值的简单查询 (由于缺少记录而产生错误值的 )
答案 0 :(得分:1)
您可以构建一个temporary table,其中包含所需的日期。并使用该表 LEFT OUTER JOIN “DepreciationTransaction”表。
SELECT dt.date_value, dt.itemid, ISNULL(SUM(dt.MonthlyDep), 0)
FROM tmp_date
LEFT OUTER JOIN
DepreciationTransaction AS dt
ON tmp_date.date_value = dt.DateOfDep
GROUP BY dt.date_value, dt.itemid
当然,如果您希望报告所有项目,则应使用tmp_date和items_id制作cartesian product。
答案 1 :(得分:1)
这里的问题是您必须生成数据。 MySQL不是为了生成数据,你应该在应用程序级别这样做,并告诉MySQL存储它。在这种情况下,应用程序应检查是否有丢失的记录,并在需要时创建它们。
除此之外,您可以(非常)使用MySQL创建动态数据:
select il.itemId, endOfMonths.aDate from ((
select aDate from (
select @maxDate - interval (a.a+(10*b.a)+(100*c.a)+(1000*d.a)) day aDate from
(select 0 as a union all select 1 union all select 2 union all select 3
union all select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9) a, /*10 day range*/
(select 0 as a union all select 1 union all select 2 union all select 3
union all select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9) b, /*100 day range*/
(select 0 as a union all select 1 union all select 2 union all select 3
union all select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9) c, /*1000 day range*/
(select 0 as a union all select 1 union all select 2 union all select 3
union all select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9) d, /*10000 day range*/
(select @minDate := (select min(dateAcquired) from il),
@maxDate := '2012-03-01') e
) f
where aDate between @minDate and @maxDate and aDate = last_day(aDate)
) endOfMonths, il)
left join dt
on il.itemId = dt.itemId and endOfMonths.aDate = dt.dateOfDep
where dt.itemId is null and last_day(il.dateAcquired) < endOfMonths.aDate
根据日期范围的长度,您可以通过删除表格(d,c,b和a)并从中删除它们来减少动态生成结果的数量(10000天意味着超过27年的记录,每个代表一天)上层公式。设置@minDate和@maxDate变量将允许您指定要过滤结果的日期。在您的情况下,此日期应该是您拥有商品的最短日期,最长日期应该是3月。
用简单的英语:如果select min(dateAcquired) from il
返回'2012-03-01' - 10000 days
之前的日期,那么您将不得不添加另一个联盟。
最后,只需添加insert语句(如果您确实需要插入这些记录)。