我有一个表中有很多不同日期的列。我知道如何从任何日期生成一个无休止的星期列表,但只有一个日期必须硬编码。
例如,如果我输入日期'1/1/2000',并且我想要这个日期之后的所有周,那么我会得到一列这个日期之后的每一周(见下文):
输入字段:
1/1/2000
输出列:
1/1/2000
1/8/2000
1/15/2000
1/22/2000
1/29/2000
……等等
然而,那只是一次约会。我要求的是做与上述相同的事情,但显示所有日期的下一个x周数(在本例中为5周)(见下文):
输入列:
1/1/2000
1/1/2001
1/1/2002
1/1/2003
1/1/2004
输出列:
1/1/2000
1/8/2000
1/15/2000
1/22/2000
1/29/2000
1/1/2001
1/8/2001
1/15/2001
1/22/2001
1/29/2001
1/1/2002
1/8/2002
1/15/2002
1/22/2002
1/29/2002
1/1/2003
1/8/2003
1/15/2003
1/22/2003
1/29/2003
1/1/2004
1/8/2004
1/15/2004
1/22/2004
1/29/2004
这个示例的输入列只有5个日期,但实际上我有包含数百个日期的列,它将不仅仅是未来的5周,更像是未来的5年
使用上面的解释,如何为列中的所有日期生成此定期列表?不只是列中第一个日期的5周(我可以这么做),而是列中每个日期接下来的5周。
3条答案
按热度按时间kyks70gy1#
使用递归cte:
这是一把小提琴。
kx1ctssn2#
天哪,伙计们。。。不要使用rcte(递归cte)来处理这些事情(任何带有增量的事情)。即使是很小的行数,对于资源使用和较差的性能来说,它们也是非常令人讨厌的。一个写得好的while循环将击败它。
有一些方法可以关闭rcte、循环和其他形式的rbar。这篇文章太长了,不能在这里重复,但这里有一篇文章介绍了一些性能和资源使用度量。
隐藏rbar:递归cte计数
首先,创建这个有用的函数
首先,我们需要一个叫做“t-sql的瑞士军刀”的工具的帮助。它是一个itvf(内联表值函数)形式的“计数表”,它是以伊兹克-本-甘首先规定和描述的方式构建的。下面是函数的代码(fntally)。文档比代码长得多。
创建10000行测试数据
现在,让我们创建一点测试数据。。。只有一万次约会。除了日期(为了让它有趣),我还添加了一个以周为单位的合同长度列。
使用该功能使其简单快捷
在那之后,这个问题的代码就简单多了(我添加了一些列只是为了演示的目的。。。去掉你不想要或不需要的东西)。
演出
以下是性能数据。。。
rcte示例
下面是rcte的一个版本,它将开始日期乘以合同周数,然后将其转储到一个表中。
性能和这是从运行的统计数据。。。比较逻辑读取、cpu和持续时间。这仅仅是10000行的输入和130万行的输出。。。和fntally方法一样。。。
这里的底线是rcte
使用了约235次或23500%的读取次数
cpu使用量增加约10倍或1000%
花费了大约10倍或1000%的时间
对rcte的增量(计数)说“不”。
2cmtqfgy3#
好的,各位。专栏在评论我之前的文章时说。。。
不过,尽管我很想使用这个解决方案,但遗憾的是我只能以只读方式访问服务器,因此无法创建临时表或自定义函数,因此rcte选项最适合我们。
不。。。即使在这种情况下,rcte也不适合你。
首先,使用temp表只是为了构建测试数据,因为我没有访问op发布的原始表的权限。它们只是为了测试。。。他们不是解决方案的一部分。以这种方式创建测试数据在受访者中是一种非常常见的做法,您只需认识到这一事实,并用实际表的实际名称替换临时表的名称。
专栏还写了以下内容。。。
但是,我们的服务器一直存在性能问题,所以我很高兴您给了我这个更好的替代解决方案,希望有一天我们真的需要优化时可以使用它。
我的看法是。。。为什么要等?从现在开始。将fntally函数的代码提交给dba,说明为什么它应该是每个数据库的一部分,或者至少包含在可访问的实用程序数据库中。如果dba真的很在行,他可能已经有了类似的东西(希望不是基于rcte或while循环),你只需要问一下就可以了。
如果这是不可能的,那么这个问题仍然可以做同样的效果(高性能,短代码,正确的答案),但是,由于你不能做“想在盒子外面”的事情,你必须花一些时间来“想在盒子里面”。
既然如此,而且您需要将temp表的名称更改为一个真实的表(我使用了上一个回复中的temp表来测试它),下面稍微长一点的代码使用类似的ccte(cascading cte)代码来替换无法生成的fntally函数。
底线是,这是很容易避免恐怖的rcte产生和增量计数,即使是这样的东西。你只需要教会自己如何在你所局限的盒子里思考d