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 に答える