我有一个大的(1GB的cvs文件)季度财务数据集,我需要填写每月数据。每行都有公司标识符和日期戳,但不同的公司有不同的报告日期(3月,6月,9月,12月对2月,5月,8月,11月)。
表:来源
Co. |Date |NPAT |Debt
A |31-Dec-09 |123 |4,000
B |29-Feb-10 |12 |300
A |31-Mar-10 |200 |4,500
B |31-May-10 |11 |200
A |30-Jun-10 |159 |4,300
C |30-Jun-10 |-30 |4
在示例公司A中报告了3月,6月,9月和12月所以我需要将3月份的数字复制到4月和5月,6月复制到7月和8月,9月到10月以及11月和12月的数字复制到1月和2月。 对于B公司,报告期为2月,5月,8月和11月。
使用上面的例子我需要的是:
表:目的地
Co. |Date |NPAT |Debt
A |31-Dec-09 |123 |4,000
A |31-Jan-10 |123 |4,000
A |29-Feb-10 |123 |4,000
B |29-Feb-10 |12 |300
A |31-Mar-10 |200 |4,500
B |31-Mar-10 |12 |300
A |30-Apr-10 |200 |4,500
B |30-Apr-10 |12 |300
A |31-May-10 |200 |4,500
....
我使用内部联接创建了一个填充表,从而生成了所有公司和日期的唯一列表,因此我实际上从包含公司和日期组合的完整列表的空表中盯着。但是我很难从哪里开始。
我正在使用mysql和R来完成这个项目,我很高兴能找到解决方案/建议。鉴于我正在寻找相当有效的实施数据量。
存在以下挑战: 1 - 公司在整个时间段内都不存在,所以我不想无限期地复制最后期限的结果(最多2个月)。同样,在早期阶段会有没有数据的公司。 2 - 不仅报告期间可能不同,但它们也可能会发生变化,因此公司最初可能会报告3月份日历,但随后会更改为2月或1月,因此在复制之前需要检查是否已有数据存在。
感谢您的帮助。
答案 0 :(得分:5)
最简单的方法是复制未来两个月的数据, 但如果公司改变其报告日期,将会出现问题。
-- Pseudo-code
CREATE VIEW Tmp1 AS
SELECT Id,
Date AS Reported_Date,
Date,
Value1, Value2
FROM QuarterlyData
UNION
SELECT Id,
Date AS Reported_Date,
Date + '1 month' AS Date, -- Replace this with correct date arithmetics
Value1, Value2
FROM QuarterlyData
UNION
SELECT Id,
Date AS Reported_Date,
Date + '2 months' AS Date, -- Replace this with correct date arithmetics
Value1, Value2
FROM QuarterlyData;
以下应该更安全(它也适用于每日数据)。 如果您在表格中有所有所需的日期,请先将其与季度数据一起加入(我保留数据六个月, 因为我不知道报告日期发生变化时会发生什么: 我们最终会有超过3个月的季度吗?)。
-- Pseudo-code
CREATE VIEW Tmp2 AS
SELECT A.Id,
A.Date AS Reported_Date,
B.Date AS Date,
A.Value1, A.Value2
FROM Data A, Dates B
WHERE B.Date <= A.Date
AND A.Date < B.Date + '6 months';
然后,删除重复项。
CREATE VIEW Tmp_Dates_To_Keep AS
SELECT Id, Date, MAX(Reported_Date) AS Reported_Date
FROM Tmp1;
SELECT A.Id,
A.Date,
A.Reported_Date,
Value1, Value2
FROM Tmp2 A, Tmp_Dates_To_Keep B
WHERE A.Id = B.Id
AND A.Date = B.Date
AND A.Reported_Date = B.Reported_Date;
答案 1 :(得分:0)
我使用DATE_ADD创建一个虚拟表来连接实际的行:
SELECT DATE_ADD('2013-01-01', INTERVAL 1 HOUR) UNION SELECT DATE_ADD('2013-01-01', INTERVAL 2 HOUR) UNION SELECT DATE_ADD('2013-01-01', INTERVAL 3 HOUR) UNION SELECT DATE_ADD('2013-01-01', INTERVAL 4 HOUR) ... etc