4

我有一组大型(cvs 文件中的 1GB)季度财务数据,我需要将其填充到月度数据中。每行都有一个公司标识符和日期戳,但不同的公司有不同的报告日期(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 月,因此在复制之前需要检查该数据是否已经存在。

谢谢你的帮助。

4

2 回答 2

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;
于 2012-04-08T10:01:14.227 回答
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
于 2015-03-22T13:34:07.037 回答