我想知道为什么我不能创建以下T-SQL函数:
CREATE FUNCTION DaysIncarceratedInYear
--Requires a Patient ID and a year
-- will return the number of days the patient was incarcerated for the year
--incarcerated is stored in a flowsheet
-- the FlowdataID are:
-- Incarceration Start Date: 'ZZZZZ00071
-- Incarceration End Date : 'ZZZZZ00072'
(
@PID varchar(10),
@YEAR int
)
RETURNS int
--DECLARE @PID varchar(10)
--DECLARE @YEAR int
--set @PID = 'ZZZZZ000L6'
--set @YEAR =2012
AS
BEGIN
declare @R int
SELECT @R = Numdays from (
;with startdates as
(
SELECT
dbo.View_PatientFlowValue.FlowValue_Value as val,
ROW_NUMBER() OVER(ORDER BY dbo.View_PatientFlowValue.FlowValue_Value) AS RowNumber
FROM dbo.View_PatientFlowValue
WHERE dbo.View_PatientFlowValue.FlowData_ID = 'ZZZZZ00071'
AND dbo.View_PatientFlowValue.FlowValue_RecordState<>1
AND Patient_ID = @PID
)
,enddates as
(
SELECT
dbo.View_PatientFlowValue.FlowValue_Value val,
ROW_NUMBER() OVER(ORDER BY dbo.View_PatientFlowValue.FlowValue_Value) AS RowNumber
FROM dbo.View_PatientFlowValue
WHERE dbo.View_PatientFlowValue.FlowData_ID = 'ZZZZZ00072'
AND dbo.View_PatientFlowValue.FlowValue_RecordState<>1
AND Person_ID = @PID
)
Select sum(DATEDIFF(d,CalcStart, CalcEnd)) as NumDays
from (
select
case
when DATEDIFF(d, cast(str(@YEAR*10000+1*100+1) as date), s.val) < 1 then '1/1/' + str(@YEAR)
else s.val
end As CalcStart,
ISNULL(e.Val, cast(str((@YEAR+1)*10000+1*100+1) as date)) as CalcEnd,
s.val as realstart, e.val as realend
FROM StartDates s
LEFT OUTER JOIN EndDates e ON s.RowNumber = e.RowNumber
) accountforyear
)
return @R
END
GO
它声明“;”附近的语法不正确,但如果我拿“;” out,它告诉我关键字“with”附近有不正确的语法。这里的语法是什么?
此查询可以很好地独立运行。
答案 0 :(得分:3)
我从未见过CTE作为子查询。
尝试重写为
;
with startdates as
(
... copy everything
)
Select @R = sum(DATEDIFF(d,CalcStart, CalcEnd))
FROM ...
return @R
答案 1 :(得分:2)
您需要将with
语句放在select
:
with startdates as
(
SELECT
dbo.View_PatientFlowValue.FlowValue_Value as val,
ROW_NUMBER() OVER(ORDER BY dbo.View_PatientFlowValue.FlowValue_Value) AS RowNumber
FROM dbo.View_PatientFlowValue
WHERE dbo.View_PatientFlowValue.FlowData_ID = 'ZZZZZ00071'
AND dbo.View_PatientFlowValue.FlowValue_RecordState<>1
AND Patient_ID = @PID
)
,enddates as
(
SELECT
dbo.View_PatientFlowValue.FlowValue_Value val,
ROW_NUMBER() OVER(ORDER BY dbo.View_PatientFlowValue.FlowValue_Value) AS RowNumber
FROM dbo.View_PatientFlowValue
WHERE dbo.View_PatientFlowValue.FlowData_ID = 'ZZZZZ00072'
AND dbo.View_PatientFlowValue.FlowValue_RecordState<>1
AND Person_ID = @PID
)
Select @R = sum(DATEDIFF(d,CalcStart, CalcEnd)) as NumDays
from (
select
case
when DATEDIFF(d, cast(str(@YEAR*10000+1*100+1) as date), s.val) < 1 then '1/1/' + str(@YEAR)
else s.val
end As CalcStart,
ISNULL(e.Val, cast(str((@YEAR+1)*10000+1*100+1) as date)) as CalcEnd,
s.val as realstart, e.val as realend
FROM StartDates s
LEFT OUTER JOIN EndDates e ON s.RowNumber = e.RowNumber
) accountforyear;
因此,@R =
在select
with
之后进入{{1}} 。这里不需要子查询,所以我只是添加了赋值。
答案 2 :(得分:0)
在查询之前定义您的CTE:
;with CTE_A( ColA, ColB)
as
(
select
ColA
, ColB
from
SomeTable
)
,CTE_B( ColA, ColC )
as
(
select
ColA
, ColC
from
SomeTable2
)
select
*
from
CTE_A a
inner join CTE_B b
on a.ColA = b.ColB