SQL code to generate new rows based on an existing rows

若如初见. 提交于 2019-12-24 09:29:33

问题


A recent question of mine gave me a simple method of generating data in a format like this:

Date        1.0 2.0 3.0 Completed
2017-01-01  10  10  5   0
2017-02-01  10  10  5   5
2017-03-01  15  10  5   15
2017-04-01  15  10  5   25

That data represents the "burnup" data for an Agile project. That is just the past data, though, and we need to predict the future data too. Only the Date and the Completed values will change in the future, and they will increment by values in another table, like

Project  Velocity  Days
Foo      25        14
Bar      35        21

I need to generate additional rows in the 1st table, with the Date and Completed values incrementing by the values in the 2nd table, like this:

Date        1.0 2.0 3.0 Completed
2017-04-15  15  10  5   50
2017-04-29  15  10  5   75
2017-05-13  15  10  5   100
2017-05-28  15  10  5   125

Do not yet have the number of additional rows needed (how far into the future to predict), but I'm shooting for 10 additional rows for now.

Since SQL doesn't seem to be big into FOR loops, how could I generate these additional rows and UNION them (or something else) with the original data?

UPDATE #1: Based on the comments, I looked into a Numbers table (something else about SQL I had never heard of!), created one, and used it like this:

DECLARE @EndDate date = '20170731'

DECLARE @StartDate date = (select top 1 Date from VersionHistory order by Date DESC)
DECLARE @StartCompleted int = (select top 1 StoryPoints from VersionHistory where Version='Completed' order by Date DESC)
DECLARE @DateIncrement int = (select top 1 Days from Velocities)
DECLARE @Velocity int = (select top 1 Velocity from Velocities)

SELECT 
  [Date] = DATEADD(DAY, Number * @DateIncrement, @StartDate),
  [StoryPoints] = @StartCompleted + Number * @Velocity
FROM dbo.Numbers
WHERE Number <= DATEDIFF(DAY, @StartDate, @EndDate)/@DateIncrement
ORDER BY Date;

This generated the new "future" values like this:

Date        StoryPoints
2017-04-15  50
2017-04-29  75
2017-05-13  100
2017-05-27  125
2017-06-10  150
2017-06-24  175
2017-07-08  200
2017-07-22  225

This is almost all the way. I still need to "repeat" the values from the other columns in the original table, so that the final output looks like this:

Date        1.0 2.0 3.0 Completed
2017-04-15  15  10  5   50
2017-04-29  15  10  5   75
2017-05-13  15  10  5   100
2017-05-28  15  10  5   125
...

Since my original data is just coming from another statement (see related question), how can I grab those values from the LAST row in that data and include in this new data? Remember that the column names are NOT known in advance, other than Date and Completed.

I assume I'll have to change my original data to store it in a temp table to extract what I need, store this new Numbers-table derived data in another temp table, and then UNION them, but I'm stuck on some of the mechanics of this.


回答1:


Thanks for the great comments. I was able to use a Numbers table to help create the "predicted" rows for my table. It was a little difficult to get the values from the last row (of original data) of certain columns (@columnsVersions) to use in this, but here's the code for using those values (@versionValues) and populating additional rows in the table:

DECLARE @StartDate date = (select top 1 Date from VersionHistory where project=@Project and Version='Completed' order by Date DESC)
DECLARE @StartCompleted int = (select top 1 StoryPoints from VersionHistory where project=@Project and Version='Completed' order by Date DESC)
DECLARE @DateIncrement int = (select top 1 Days from Velocities where project = @Project)
DECLARE @Velocity int = (select top 1 Velocity from Velocities where project = @Project)
DECLARE @EndDate date = '2017-12-31'

set @q='
insert into #T1 (Date, Predicted, ' + @columnsVersions + ') 
SELECT 
  DATEADD(DAY, Number * ' + CONVERT(varchar(10), @DateIncrement) + ',''' + CONVERT(varchar(10), @StartDate) + ''')
  ,' + CONVERT(varchar(10), @StartCompleted) + ' + Number * ' + CONVERT(varchar(10), @Velocity) + '
  ,' + @versionValues + '
FROM dbo.Numbers
WHERE Number <= DATEDIFF(DAY,''' + CONVERT(varchar(10),@StartDate) + ''',''' + CONVERT(varchar(10), @EndDate) + ''')/' + CONVERT(varchar(10),@DateIncrement)

exec(@q)
select * from #T1


来源:https://stackoverflow.com/questions/45194835/sql-code-to-generate-new-rows-based-on-an-existing-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!