我有一个包含这些列的表
- ProjectId
- Generation
- Expected
- CarryOver
我正试图以这种方式更新我已经填充的表:
Generation = Integral Part of ((Generation + CarryOver of Previous Row)/10 )
CarryOver = decimal part of ((Generation + CarryOver of Previous Row)/10 )
其中Previous Row和Current Row都具有相同的projectId
以下是用于实现此目的的查询:
UPDATE TTable
SET
TTable.Expected=(TTable.Generation+ ISNULL(STable.CarryOver,0)),
TTable.CarryOver =(TTable.Generation+ISNULL(STable.CarryOver,0))-CONVERT(INT,(TTable.Generation+ISNULL(STable.CarryOver,0)))
FROM
(
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
)TTable,
(
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
) STable
Where
TTable.RowNumber = STable.RowNumber+1 AND
TTable.ProjectId = STable.ProjectId
....但是发生了一些奇怪的事情,更新只发生在前两行。对于其他行,
ISNULL(STable.CarryOver,0)
返回0.为什么?
请帮我。或者提出一些其他方法来实现这个目标
编辑:运行查询
ProjectId MonthYear Month Year Generation Expected CarryOver
10 2011-10-01 00:00:00.000 10 2011 56.748 56 0.748
10 2011-11-01 00:00:00.000 11 2011 12.004 12 0.752
10 2011-12-01 00:00:00.000 12 2011 10.632 10 0.632
10 2012-01-01 00:00:00.000 01 2012 11.928 11 0.928
10 2012-02-01 00:00:00.000 02 2012 7.580 7 0.580
100 2011-12-01 00:00:00.000 12 2011 5.897 5 0.897
100 2012-01-01 00:00:00.000 01 2012 0.881 1 0.778
如上所示生成数据。请注意3row
之后逻辑如何不起作用原始输出。在运行更新查询之前:
ProjectId MonthYear Month Year Generation Expected CarryOver
10 2011-10-01 00:00:00.000 10 2011 56.748 56 0.748
10 2011-11-01 00:00:00.000 11 2011 12.004 NULL NULL
10 2011-12-01 00:00:00.000 12 2011 10.632 NULL NULL
10 2012-01-01 00:00:00.000 01 2012 11.928 NULL NULL
10 2012-02-01 00:00:00.000 02 2012 7.580 NULL NULL
100 2011-12-01 00:00:00.000 12 2011 5.897 5 0.897
100 2012-01-01 00:00:00.000 01 2012 0.881 NULL NULL
答案 0 :(得分:0)
以下查询将为您提供预期结果
(对于那些想要玩的人来说,测试代码https://gist.github.com/1969171)
PID Date M Y Generation Expected CarryOver
10 2011-10-01 10 2011 56.748 56 0.748
10 2011-11-01 11 2011 12.004 12 0.752
10 2011-12-01 12 2011 10.632 11 0.384
10 2012-01-01 01 2012 11.928 12 0.312
10 2012-02-01 02 2012 7.58 7 0.892
100 2011-12-01 12 2011 5.897 5 0.897
100 2012-01-01 01 2012 0.881 1 0.778
DECLARE rowItems CURSOR FOR
SELECT ProjectId, [Month], [Year], Generation FROM TTable
ORDER BY ProjectId,[Year] ,CAST([Month] as int)
DECLARE @p int, @m VARCHAR(5), @y int, @g FLOAT, @priorP int,
@carryOver FLOAT, @expected FLOAT
OPEN rowItems
FETCH NEXT FROM rowItems INTO @p, @m, @y, @g
SET @priorP = -1
SET @carryOver = 0.0
WHILE @@FETCH_STATUS = 0
BEGIN
IF NOT @p = @priorP SET @carryOver = 0.0
SET @expected = @g+@carryOver
SET @carryOver = ROUND(@expected-FLOOR(@expected),3,0)
UPDATE TTable
SET EXPECTED = FLOOR(@expected), CarryOver = @carryOver
WHERE ProjectId = @p and [Month] = @m and [Year] = @y
SET @priorP = @p
FETCH NEXT FROM rowItems INTO @p, @m, @y, @g
END
CLOSE rowItems
DEALLOCATE rowItems
SELECT * FROM TTable
您需要循环执行此操作。您使用的查询是获取结转列的原始值而不是更新的值。
答案 1 :(得分:0)
对此表示抱歉。这是我的建议。
测试数据
CREATE TABLE TTable
(
ProjectId INT,
MonthYear DATETIME,
Month VARCHAR(5),
Year INT,
Generation FLOAT,
Expected FLOAT,
CarryOver FLOAT
)
INSERT INTO TTable
VALUES
(10,'2011-10-01 00:00:00.000','10',2011,56.748,56,0.748),
(10,'2011-11-01 00:00:00.000','11',2011,12.004,NULL,NULL),
(10,'2011-12-01 00:00:00.000','12',2011,10.632,NULL,NULL),
(10,'2012-01-01 00:00:00.000','01',2012,11.928,NULL,NULL),
(10,'2012-02-01 00:00:00.000','02',2012,7.580,NULL,NULL),
(100,'2011-12-01 00:00:00.000','12',2011,5.897,5,0.897),
(100,'2012-01-01 00:00:00.000','01',2012,0.881,NULL,NULL)
<强>查询强>
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY tbl.ProjectId,tbl.Month) AS RowNbr,
tbl.ProjectId,
tbl.MonthYear,
tbl.Month,
tbl.Year,
tbl.Generation,
(
FLOOR(tbl.Generation)
) AS Expected,
(
ROUND(tbl.Generation-FLOOR(tbl.Generation),3,0)
)AS CarryOver
FROM
TTable AS tbl
)
SELECT
CTE.ProjectId,
CTE.MonthYear,
CTE.Month,
CTE.Year,
CTE.Generation,
CTE.Expected,
(
CTE.CarryOver+ISNULL(Previus.CarryOver,0)
) AS CarryOver
FROM
CTE
LEFT JOIN CTE AS Previus
ON CTE.RowNbr=Previus.RowNbr+1
<强>结果强>
ProjectId MonthYear Month Year Generation Expected CarryOver
10 2011-10-01 00:00:00.000 10 2011 56,748 56 0,748
10 2011-11-01 00:00:00.000 11 2011 12,004 12 0,752
10 2011-12-01 00:00:00.000 12 2011 10,632 10 0,636
10 2012-01-01 00:00:00.000 01 2012 11,928 11 1,56
10 2012-02-01 00:00:00.000 02 2012 7,58 7 1,508
100 2011-12-01 00:00:00.000 12 2011 5,897 5 1,477
100 2012-01-01 00:00:00.000 01 2012 0,881 0 1,778
更新查询
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY tbl.ProjectId,tbl.Month) AS RowNbr,
tbl.ProjectId,
tbl.MonthYear,
tbl.Month,
tbl.Year,
tbl.Generation,
(
FLOOR(tbl.Generation)
) AS Expected,
(
ROUND(tbl.Generation-FLOOR(tbl.Generation),3,0)
)AS CarryOver
FROM
TTable AS tbl
)
UPDATE TTable
SET TTable.CarryOver=CTE.CarryOver+ISNULL(Previus.CarryOver,0),
TTable.Expected=CTE.Expected
FROM
(
SELECT
ROW_NUMBER() OVER(ORDER BY TTable.ProjectId,
TTable.Month) AS RowNbr,
TTable.CarryOver,
TTable.Expected
FROM
TTable
) AS TTable
JOIN CTE
ON TTable.RowNbr=CTE.RowNbr
LEFT JOIN CTE AS Previus
ON CTE.RowNbr=Previus.RowNbr+1
现在选择更新的表格时。然后你会得到这个结果:
ProjectId MonthYear Month Year Generation Expected CarryOver
10 2011-10-01 00:00:00.000 10 2011 56,748 56 0,748
10 2011-11-01 00:00:00.000 11 2011 12,004 12 0,752
10 2011-12-01 00:00:00.000 12 2011 10,632 10 0,636
10 2012-01-01 00:00:00.000 01 2012 11,928 11 1,56
10 2012-02-01 00:00:00.000 02 2012 7,58 7 1,508
100 2011-12-01 00:00:00.000 12 2011 5,897 5 1,477
100 2012-01-01 00:00:00.000 01 2012 0,881 0 1,778
答案 2 :(得分:0)
我就这样做了:
更新与每个ProjectId对应的第一条记录:
Update TTable
SET
TTable.Expected=(TTable.Generation/10),
TTable.CarryOver =(TTable.Generation/10)-CONVERT(INT,TTable.Generation/10)
FROM
(
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
) TTable where TTable.RowNumber in
(
Select Min(TTable.RowNumber)as RowNumber From
(
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
) as TTable GROUP by ProjectId
)
更新其余记录:
DECLARE @RowNumber INT = -99
DECLARE @CarryOver decimal(4,3) =0
DECLARE @Expected INT =0
DECLARE @ProjectId int =0
WHILE @RowNumber IS NOT NULL
BEGIN
SET @RowNumber= (SELECT MIN(RowNumber) FROM (
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
) as TTable
WHERE TTable.RowNumber> @RowNumber)
IF @RowNumber IS NULL
BREAK
SELECT @CarryOver= TTable.CarryOver,@ProjectId=TTable.ProjectId FROM
(
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
) as TTable where TTable.RowNumber = @RowNumber
UPDATE TTable
SET TTable.Expected =(TTable.Generation+@CarryOver)/10,
CarryOver = (TTable.Generation+@CarryOver)/10 - CONVERT(INT,(TTable.Generation+@CarryOver)/10)
FROM
(
SELECT ROW_NUMBER()OVER(order by ProjectId,MonthYear) as RowNumber,ProjectId,
[MonthYear],[Month],[Generation],[Expected],[CarryOver]
FROM #SRECEsimated
) as TTable where TTable.RowNumber = @RowNumber+1 AND TTable.ProjectId=@ProjectId
END