使用先前记录中的数据填充SQL查询中的空白月份

时间:2016-12-22 11:00:27

标签: sql sql-server sql-server-2008

我试图在几个月内填写SQL查询中前几个月的数据。我有一张表,其中包含记录物品租赁的记录。只有在租借或退回物品时才会在表格中创建记录。我需要每月概述每家公司(客户)需要支付的费用。

表格如下:

Companyname  itemID               logdate          costcalc 
Company A   VB004536    2015-11-10 16:41:25.000     false   
storage     VB004536    2015-10-27 16:15:44.000     false   
Company z   VB004536    2015-10-15 08:31:17.000     false   
Company A   VB004536    2015-09-24 08:47:56.000     false   
storage     VB004536    2015-09-03 11:34:45.000     false   
Company z   VB004536    2015-07-02 08:23:41.000     true    
storage     VB004536    2015-06-10 13:22:27.000     false
Company c   VB004536    2015-05-18 09:57:20.000     false   
Company c   VB004536    2015-01-19 14:01:49.000     false   

我想要的结果是:

Companyname  itemID               logdate          costcalc 
Company A   VB004536    2015-11-10 16:41:25.000     false   
storage     VB004536    2015-10-27 16:15:44.000     false   
Company z   VB004536    2015-10-15 08:31:17.000     false   
Company A   VB004536    2015-09-24 08:47:56.000     false   
storage     VB004536    2015-09-03 11:34:45.000     false   
Company z   VB004536    2015-08-02 08:23:41.000     true    based on the prev row
Company z   VB004536    2015-07-02 08:23:41.000     true    
storage     VB004536    2015-06-10 13:22:27.000     false
Company c   VB004536    2015-05-18 09:57:20.000     false   
Company c   VB004536    2015-04-19 14:01:49.000     false   based on the prev row
Company c   VB004536    2015-03-19 14:01:49.000     false   based on the prev row
Company c   VB004536    2015-02-19 14:01:49.000     false   based on the prev row
Company c   VB004536    2015-01-19 14:01:49.000     false   

例如,Company cVB004536上租用了项目2015-01-19,并且在2016-06-10之前未将其返回存储空间,然后Company z2015-07-02租借它{1}}等等。

我尝试了类似的查询:

SELECT ROW_NUMBER OVER (PARTITION BY Companyname ORDER BY logdate DESC) AS rownum, 
       Companyname,
       logdate, 
       itemID,
       costcalc,  
       LAG(itemID,costcalc, 1,0) as prev_row

但SQL 2008不支持LAG,也不会用适当的数据填写所有缺失的月份。

我不知道如何(或者甚至)如何做到这一点,以及随着时间的推移,实现它的任何方法是否具有足够高的性能。任何人都可以建议一个解决方案来获得我需要的输出吗?

1 个答案:

答案 0 :(得分:0)

使用简化的Months表代替完整的日历表:

CREATE TABLE Months (
    [Month] DATETIME
)

INSERT INTO Months
SELECT '2015-01-01'
UNION
SELECT '2015-02-01'
UNION
SELECT '2015-03-01'
UNION
SELECT '2015-04-01'
UNION
SELECT '2015-05-01'
UNION
SELECT '2015-06-01'
UNION
SELECT '2015-07-01'
UNION
SELECT '2015-08-01'
UNION
SELECT '2015-09-01'
UNION
SELECT '2015-10-01'
UNION
SELECT '2015-11-01'
UNION
SELECT '2015-12-01'

我相信这个查询可以提供您想要的结果:

SELECT ISNULL(l.ItemId,previous.ItemId) AS ItemId,
       ISNULL(l.LogDate,FORMAT(m.[Month],'yyyy-MM-') + FORMAT(previous.LogDate,'dd HH:mm:ss.000')) AS LogDate,
       ISNULL(l.CompanyName,previous.CompanyName) AS CompanyName,
       ISNULL(l.CostCalc,previous.CostCalc) AS CostCalc
FROM Months m
LEFT JOIN ItemLog l ON FORMAT(l.LogDate, 'MMM yyyy') = FORMAT(m.[Month], 'MMM yyyy')
OUTER APPLY
(
    SELECT TOP 1 ItemId, LogDate, CompanyName, CostCalc
    FROM ItemLog prev
    WHERE prev.LogDate < m.[Month]
    ORDER BY prev.LogDate DESC
) previous
ORDER BY ISNULL(l.LogDate,FORMAT(m.[Month],'yyyy-MM-') + FORMAT(previous.LogDate,'dd HH:mm:ss.000')) DESC

如果您的表格中有多种ItemId值(我怀疑您这样做),您需要进行一些细微的更改,但这至少应该向您展示一种可能的方式。起点。