0

首先我给你解释一下情况。

我想将数据从一个表(View_Solidnet_Training)传输到另一个表(OBJ_Availability)。有一个问题:在视图中有一个开始日期和结束日期!在OBJ_Availability每个日期都有一个记录。所以视图中的一行在另一个表中有多行。

我必须与 CTE 合作。所以光标对我来说是没有选择的。中间WITH运行完美,但是当我想添加一个额外的WITH以检查是否ID不为零时,它必须更改变量@Start并更改@End为视图中的新记录。

对不起,我的英语不太好,但我希望你能理解情况。

这是我的代码:

DECLARE @Start AS DATETIME;
DECLARE @End AS DATETIME;
SET @Start = '2013-04-09';
SET @End = '2013-04-11';
with cte1 as 
(

with cte2 as
(
select @Start as DateValue
union all

select DateValue + 1
from cte2
where DateValue + 1 <= @End
)
into OBJ_Availability  
select 34, DateValue, 'AM', 2, 'Test' from cte2
)
select * from cte1 where PK_Training_ID is not null;

像这样的东西,但我不明白它从哪里获取视图的信息。我从来没有在任何地方提到过这个名字?

4

1 回答 1

0

我还不能发表评论,所以在回答之前我需要问你几个问题。

1、CTE的名字怎么和view的名字一样?它永远不会起作用。

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
于 2013-04-09T09:26:34.190 回答