我试图在几个月内填写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 c
在VB004536
上租用了项目2015-01-19
,并且在2016-06-10
之前未将其返回存储空间,然后Company z
从2015-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
,也不会用适当的数据填写所有缺失的月份。
我不知道如何(或者甚至)如何做到这一点,以及随着时间的推移,实现它的任何方法是否具有足够高的性能。任何人都可以建议一个解决方案来获得我需要的输出吗?
答案 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
值(我怀疑您这样做),您需要进行一些细微的更改,但这至少应该向您展示一种可能的方式。起点。