SQL Server 2008:n次重复一行,其中n是字段中的值

时间:2019-03-14 10:18:01

标签: sql sql-server sql-view

在SQL Server 2018中,我有三个表:

T1 (idService, dateStart, dateStop)
T2 (idService, totalCostOfService)
T3 (idService, companyName)

使用联接,我创建了一个视图:

V1 (idService, dateStart, dateStop, totalCostOfService, companyName)

我们很好。我可以在视图上进行选择,并获取已完成服务的列表。

我现在想做的是将视图的每一行重复n次,其中 n = dateStart-dateStop ;每行应有一个“新” totalCostOfService = totalCostOfService / n

我可以使用临时表,声明变量,使用一些 while 等在temp中进行插入等操作。将其称为“过程”

但是我想了解的是:

是否可以通过在V1上进行选择直接执行此操作?如果没有,是否可以将“过程”另存为视图,以便我可以轻松选择呢?

对不起,如果我的问题看起来有些愚蠢,但是我对SQL完全陌生。我尝试在这里和Google上进行搜索,但找不到我的问题的答案。

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用Tally Table而不是rCTE(即RBAR):

WITH N AS (
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
         CROSS JOIN N N4) --10000
SELECT *
FROM YourTable
     JOIN Tally T ON T.I <= dateStart-dateStop --Assumes dateStart and DateStop are integer values, even though their name implies otherwise
                                               --If they are dates, then use DATEDIFF(DAY, dateStart, dateEnd)

该计数将产生最多10000个数字(超过27年的天数。这应该绰绰有余)。

答案 1 :(得分:0)

我将假设存在一个numbers表,该表具有用于各个值编号的列val。如果您不这样做,则可以通过四处搜索找到很多东西。

在视图的FROM子句的末尾添加此内容:

cross apply (select datediff(day,T1.dateStart,T1.dateStop)+1 as n_days)q1 -- number of days INCLUDING start
cross apply (select dateadd(day,T1.dateStart,n.val) as day_of_charge)q2 from numbers n where n.val between 0 and n_days-1)

然后您将在SELECT上具有以下字段:

T2.totalCostOfService/n_days as totalCostOfService

我将很快添加一个数字表解决方案。

答案 2 :(得分:0)

您可以使用递归CTE:

with cte as (
      select idService, dateStart, dateStop,
             totalCostOfService / (datediff(day, datestop, datestart) + 1) as dailyCostOfService,
             companyName
      from v1
      union all
      select idService,
             dateadd(day, 1, dateStart),
             dateStop,
             dailyCostOfService
             companyName
      from cte
     )
select idservice, dateStart as dateOfService,
       dailyCostOfService, companyName
from cte;

请注意,如果任何一行中的天数都超过100天,则需要添加OPTION (MAXRECURSION 0)