首先,我会向你解释情况。
我想将数据从一个表(View_Solidnet_Training)传输到另一个表(OBJ_Availability)。
有一个问题:在视图中有一个Start-和EndDate!在OBJ_Availability
中,每个日期都有一条记录。因此视图中的一行在另一个表中有多行。
我必须与CTE合作。所以光标对我来说是没有选择的。
中间WITH
运行完美,但当我想添加额外WITH
以检查ID
是否不为零时,它必须更改变量@Start
和{{ 1}}到视图中的新记录。
对不起我的英语,这不是那么好,但我希望你了解情况。
这是我的代码:
@End
这样的东西,但我不明白它从何处获取视图的信息。我从来没有在任何地方提到这个名字?
答案 0 :(得分:0)
我还不能发表评论,所以在回答之前我需要问几个问题。
1,为什么CTE的名称与视图的名称相同?它永远不会起作用。
2,你的意思是'检查ID是否不为零,它必须将变量@Start和@End更改为视图中的新记录',我无法弄清楚为什么你需要这样做空检查
3,您确定可以使用DateValue + 1来获取下一个日期吗?你应该使用DATEADD吗?
最后,你不能在CTE中使用CTE,这是行不通的。在CTE中声明变量也不可能。
这是我最好的客人:
首先,正如您所提到的,您的视图有一个startdate列和一个enddate列,
所以我假设视图中有StartDate和EndDate列,这是我的sql:
DECLARE @start AS DATETIME
DECLARE @end AS DATETIME
SELECT @start = min(StartDate)
from View_Solidnet_Training
where PK_Training_ID is not null
SELECT @end = max(EndDate)
from View_Solidnet_Training
where PK_Training_ID is not null
;with cte_dates as
(
select @start DateValue
union all
select DateValue + 1
from cte_dates
where DateValue + 1 <= cast(@end as datetime)
)
into OBJ_Availability
select v.PK_Training_ID, DateValue, 'AM', 2, 'Test' --columns from the view
from cte_dates cte
join View_Solidnet_Training v on v.StartDate < cte.DateValue and cte.DateValue < v.EndDate
where v.PK_Training_ID is not null
max()和min函数计算出视图中最新和最旧的日期
然后CTE cte_dates创建一个从@start到@end的日期列表
然后加入CTE将在StartDate到EndDate
的范围内重复记录希望这个帮助
顺便说一下,我的家用电脑上没有sql,所以我可以检查一下SELECT @start = min(StartDate)
from View_Solidnet_Training
where PK_Training_ID is not null
是否运行,但你应该明白
使用while而不是CTE:
DECLARE @start AS DATETIME
DECLARE @end AS DATETIME
SELECT @start = min(StartDate)
from View_Solidnet_Training
where PK_Training_ID is not null
SELECT @end = max(EndDate)
from View_Solidnet_Training
where PK_Training_ID is not null
DECLARE @AllDates table
(DateValue datetime)
DECLARE @dCounter datetime
SELECT @dCounter = @start
WHILE @dCounter <= @end
BEGIN
INSERT INTO @AllDates VALUES (@dCounter)
SELECT @dCounter=@dCounter+1
END
insert into OBJ_Availability
select v.PK_Training_ID, DateValue, 'AM', 2, 'Test' --columns from the view
from @AllDates d
join View_Solidnet_Training v on v.StartDate < d.DateValue and d.DateValue < v.EndDate
where v.PK_Training_ID is not null
或者您甚至可以
DECLARE @start AS DATETIME
DECLARE @end AS DATETIME
SELECT @start = min(StartDate)
from View_Solidnet_Training
where PK_Training_ID is not null
SELECT @end = max(EndDate)
from View_Solidnet_Training
where PK_Training_ID is not null
DECLARE @dCounter datetime
SELECT @dCounter = @start
WHILE @dCounter <= @end
BEGIN
insert into OBJ_Availability
select v.PK_Training_ID, DateValue, 'AM', 2, 'Test' --columns from the view
from View_Solidnet_Training v
where v on v.StartDate < @dCounter and @dCounter < v.EndDate and v.PK_Training_ID is not null
SELECT @dCounter=@dCounter+1
END