在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上进行搜索,但找不到我的问题的答案。
谢谢!
答案 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)
。