【问题标题】:SQL code to generate new rows based on an existing rows基于现有行生成新行的 SQL 代码
【发布时间】:2017-07-23 02:02:13
【问题描述】:

recent question of mine 给了我一个简单的方法来生成如下格式的数据:

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

该数据代表敏捷项目的“燃尽”数据。不过,这只是过去的数据,我们还需要预测未来的数据。将来只有 Date 和 Completed 值会发生变化,并且它们会按另一个表中的值递增,例如

Project  Velocity  Days
Foo      25        14
Bar      35        21

我需要在第一个表中生成额外的行,日期和完成值按第二个表中的值递增, 像这样:

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

还没有所需的额外行数(预测未来多长时间),但我现在打算再增加 10 行。

由于 SQL 在 FOR 循环中似乎并不重要,我如何生成这些额外的行并将它们(或其他东西)与原始数据联合起来?

更新 #1: 基于 cmets,我查看了一个 Numbers 表(我从未听说过的其他关于 SQL 的东西!),创建了一个,然后像这样使用它:

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;

这产生了新的“未来”值,如下所示:

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

这是几乎。我仍然需要“重复”原始表中其他列的值,以便最终输出如下所示:

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
...

由于我的原始数据只是来自另一个语句(请参阅related question),我如何从该数据的最后一行中获取这些值并包含在这个新数据中?请记住,除了 Date 和 Completed 之外,列名是事先不知道的。

我假设我必须更改我的原始数据以将其存储在临时表中以提取我需要的内容,将这个新的 Numbers 表派生数据存储在另一个临时表中,然后将它们联合起来,但我被困住了关于这个的一些机制。

【问题讨论】:

  • 我在 tsql 中使用递归 CTE 来处理这类事情
  • 您可以使用计数(数字)表。我不完全了解您的示例数据和所需结果之间的联系,因此我不会发布答案,但请查看加入数字表的选项。
  • 这些数据集之间有什么关系?
  • 您可以做的是将您的结果存储在您的第一篇文章的表格中。然后您可以使用一个过程来获取您的第二组数据并将其插入到该表中
  • “输入数据”(实际上是我上一篇文章的输出,链接在这篇文章的顶部)是不同软件“版本”的历史和敏捷的“速度”团队致力于故事(开发)。有一个小表定义了“未来”速度以及计算新“完成”值的频率;ue。所以,我有过去的数据,需要生成未来的数据,然后我会从中生成一个图表。

标签: sql sql-server for-loop union


【解决方案1】:

感谢伟大的 cmets。我能够使用 Numbers 表来帮助为我的表创建“预测”行。从某些列(@columnsVersions)的最后一行(原始数据)中获取值有点困难,但这里是使用这些值(@versionValues)并在表中填充其他行的代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2015-10-17
    • 2019-12-02
    相关资源
    最近更新 更多