我只想知道如何在SQl Server中编写包含CTE
的{{1}}?
我曾尝试在下面写一个CTE,我正在使用If Exists
语句选择天气记录是否存在。如果记录不存在,那么我分配默认值但是我收到错误
'关键字'if'
附近的语法不正确
“。请帮我解决这个错误并指导我写这个CTE。 请在下面找到我写过的CTE: -
If Exists
GO
当我删除这个If Exist语句时,Alter procedure St_Proc_GetTeamProductionReport
@mindate DateTime,
@maxdate DateTIme,
@userID varchar(50)
as
Begin
set NoCount on;
with
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)
as
(
if exists
(
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
where P.userid=@userID and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )
)
else
(
Select '2012-09-14 13:41:52' as CalendarDate,
2 as RoleID,'938' as UserID,
(select Userecode from Userinfo where userid=@userID) as UserECode,
(select UserName from Userinfo where userid=@userID)as UserName,
(select ImmediateSupervisor from Userinfo where userid=@userID)as ImmediateSupervisor,
'BP' as NatureOfWorkName,
'CO Processing' as RegionProjectName,
'Adams' as CountyName,
'Quality' as WorkTypeName,
'Corrections ' as TaskName,
5 as VolumneProcessed,
'01:00' as TimeSpent,
'test' as Comment
)
union all
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
inner join ProductionCTE
on U.ImmediateSupervisor=ProductionCTE.UserECode
where P.IsTaskCompleted=1 and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )
)
select distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment from ProductionCTE where RoleID=1
end
工作正常,但在添加CTE
语句后,它有错误。
答案 0 :(得分:2)
您不能以这种方式使用IF EXISTS
。公用表表达式只能包含一个select语句,不能说if condition SELECT THIS else SELECT THAT
。
看起来您正在尝试将其他创建的行添加到查询返回的结果集中。您可以通过将CTE实现为将返回单个新行的表值函数来实现此目的。
http://msdn.microsoft.com/en-gb/library/ms191165(v=sql.105).aspx
答案 1 :(得分:1)
如果您要构建UNION
,只有第一个SELECT
没有返回任何行,您才能从第二个SELECT
获得结果,您可以使用RANK()
来实现此目的。因此,您可以将真实查询放在第一个SELECT
中,将所需的默认值放在第二个中,然后获得所需的结果。
我没有你的表和数据,所以我不会尝试重新编写你的查询。但我会用这个来说明:
;With WithDefaults as (
select name,0 as Rank from sys.objects
union all
select 'abc',1 --Default if no results
), Ranked as (
select *,RANK() OVER (ORDER BY Rank) as Rnk from WithDefaults
)
select * from Ranked where Rnk = 1
返回(在我尝试过的大多数空DB上)98个结果,其中没有name
abc
。如果我们强制第一个SELECT
没有返回结果:
select name,0 as Rank from sys.objects where 1 = 2
我们现在使用name
abc
获得单行结果。
希望你能看到这对你的原始查询有什么用。
答案 2 :(得分:0)
您不能在CTE中使用IF EXISTS。但是你可以修改函数逻辑
示例:
alter procedure St_Proc_GetTeamProductionReport
@mindate DateTime,
@maxdate DateTIme,
@userID varchar(50)
as
Begin
set NoCount on;
;with
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)
as
(
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment, 1 AS cnt
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
where P.userid=@userID and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )
UNION ALL
Select '2012-09-14 13:41:52' as CalendarDate,
2 as RoleID,'938' as UserID,
(select Userecode from Userinfo where userid=@userID) as UserECode,
(select UserName from Userinfo where userid=@userID)as UserName,
(select ImmediateSupervisor from Userinfo where userid=@userID)as ImmediateSupervisor,
'BP' as NatureOfWorkName,
'CO Processing' as RegionProjectName,
'Adams' as CountyName,
'Quality' as WorkTypeName,
'Corrections ' as TaskName,
5 as VolumneProcessed,
'01:00' as TimeSpent,
'test' as Comment, 0
), ProductionCTE2 AS
(
SELECT TOP(SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE COUNT(*) END FROM ProductionCTE WHERE cnt = 1)
CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureofWorkName,
RegionProjectName,Countyname,WorktypeName,TaskName,VolumeProcessed,Timespent,Comment
FROM ProductionCTE2
union all
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
inner join ProductionCTE
on U.ImmediateSupervisor=ProductionCTE.UserECode
where P.IsTaskCompleted=1 and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )
)
select distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment
from ProductionCTE2
where RoleID=1
end
答案 3 :(得分:-1)
进出CTE
If Exists(some select statement)
DoSomething
else
DoSomethingElse
你错过了dosomething位