1

我想知道为什么我不能创建以下 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

它指出“;”附近的语法不正确 ,但如果我采用“;” 出来,它告诉我关键字“with”附近的语法不正确。这里的正确语法是什么?

此查询独立工作正常。

4

3 回答 3

3

我从未将 CTE 视为子查询。

尝试重写为

;
with startdates as
(
   ... copy everything

)
Select @R = sum(DATEDIFF(d,CalcStart, CalcEnd))
FROM ...

return @R
于 2013-03-28T18:43:37.650 回答
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这里不需要子查询,所以我只是在其中添加了分配。

于 2013-03-28T18:43:28.493 回答
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
于 2013-03-28T18:47:10.977 回答