2011-03-23 4 views
1

윈도우 이동 평균을 계산하는 함수 (예 : SQLServer 2008)를 만들려고합니다. SQL에 익숙하지 않아서 약간의 어려움을 겪고 있습니다. 이동 평균을 수행하려고하는 데이터는 일별로 그룹화되어야하며 (모든 타임 스탬프가 적용된 데이터 임) 가변적 인 이동 평균 창이 적용되어야합니다.SQL 서버의 윈도우 이동 평균

나는 아래쪽에 표시된 요일 (및 @id)까지 데이터를 그룹화하는 기능을 이미 갖추고 있습니다. 몇 가지 질문이 있습니다 :

이동 평균 기능 내에서 그룹화 기능을 호출하는 것이 좋습니까? 아니면 한 번에 모두 수행해야합니까?

함수에 날짜 입력을위한 이동 평균을 얻을 수 있지만, 반환 된 데이터의 첫 번째 N일가 0이되지 않도록 이동 평균을 시작 N일 돌아 가야 할 가능 그들의 평균은? (즉, 그들이 2011 년 1 월 1 일부터 02-08-2011까지 7 일 이동 평균을 원할 경우 01-01-2011에 이동 평균 계산을 시작하므로 정의한 첫날에 값이 있습니까?)

이동 평균을 수행하는 방법을 조사 중이며 이동 창이 가장 좋은 옵션 인 것 같습니다. (currentSum = prevSum + todayCount - nthDayAgoCount)/nDays하지만 아직 계산 중입니다. 이것의 SQL 구현.

나는 (일부 변수는 가시성을 위해 제거)과 같습니다 그룹화 기능을 가지고 :

ALL 2010-01-01 1 103 
ALL 2010-01-02 1 114 
ALL 2010-01-03 1 86 
ALL 2010-01-04 1 88 
ALL 2010-01-05 1 84 
ALL 2010-01-06 1 87 
ALL 2010-01-07 1 82 

편집 :는 대답하기 위해 테이블과 같이 반환

SELECT 
     'ALL' as GeogType, 
     CAST(v.AdmissionOn as date) as dtAdmission,  
     CASE WHEN @id IS NULL THEN 99 ELSE v.ID END, 
     COUNT(*) as nVisits 
    FROM dbo.Table1 v INNER JOIN dbo.Table2 t ON v.FSLDU = t.FSLDU5 
    WHERE v.AdmissionOn >= '01-01-2010' AND v.AdmissionOn < DATEADD(day,1,'02-01-2010') 
      AND v.ID = Coalesce(@id,ID) 
    GROUP BY  
     CAST(v.AdmissionOn as date), 
     CASE WHEN @id IS NULL THEN 99 ELSE v.ID END 
    ORDER BY 2,3,4 

첫 번째 질문 :

나는 임시 테이블을 선언하고 t에서 결과를 삽입하는 함수를 만들었습니다. 그는 그 안에 함수를 집계 한 다음 user662852의 예제를 사용하여 이동 평균을 계산합니다.

답변

2

쿼리에서 하드 코드 된 날짜 범위를 사용하십시오. 출력 (예 : 마지막 샘플)을 임시 테이블 (아래 #visits라고 함)에 씁니다.
이 자기 시도는 임시 테이블에 조인 : 나는 당신의 질문에 대한 응답으로이 말을 댓글에 충분한 공간이 없었다 :

Select list.dtadmission 
    , AVG(data.nvisits) as Avg 
    , SUM(data.nvisits) as sum 
    , COUNT(data.nvisits) as RollingDayCount 
    , MIN(data.dtadmission) as Verifymindate 
    , MAX(data.dtadmission) as Verifymaxdate 
from #visits as list 
inner join #visits as data 
on list.dtadmission between data.dtadmission and DATEADD(DD,6,data.dtadmission) group by list.dtadmission 

편집이

내를 "좀 카티 젼 조인 "왜냐하면 그것은 join 제약 조건에서 between을 사용하기 때문입니다. 목록에있는 각 레코드는 다른 모든 레코드에 대해 올라간다. 그리고 나는 내가보고 한 날짜가 (-7) 일의 하한과 오늘 사이에있는 레코드를 원한다. 모든 데이터 날짜가 날짜를 나열하는 데 사용할 수 있습니다, 이것이 귀하의 질문의 열쇠입니다.나는이

list.dtadmission between DATEADD(DD,-6,data.dtadmission) and data.dtadmission 

같은 조인 조건을 작성하지만 실제로 일어난 일은 내가

구문은 "LOW와 HIGH 사이"이기 때문에 더 레코드를 반환하지
list.dtadmission between DATEADD(DD,6,data.dtadmission) and data.dtadmission 

로 테스트했습니다 수 있었다. 나는 0 개의 레코드를 처리하고 인수를 바꿨다.

SELECT 
list.[dtAdmission] as listdate 
,data.[dtAdmission] as datadate 
,data.nVisits as datadata 
,DATEADD(dd,6,list.dtadmission) as listplus6 
,DATEADD(dd,6,data.dtAdmission) as datapplus6 
from [sandbox].[dbo].[admAvg] as list inner join [sandbox].[dbo].[admAvg] as data  
on 
1=1 
where list.dtAdmission = '5-Jan-2011' 

SELECT 
     list.[dtAdmission] as listdate 
     ,data.[dtAdmission] as datadate 
     ,data.nVisits as datadata 
     ,DATEADD(dd,6,list.dtadmission) as listplus6 
     ,DATEADD(dd,6,data.dtAdmission) as datapplus6 
from [sandbox].[dbo].[admAvg] as list inner join [sandbox].[dbo].[admAvg] as data  
on 
list.dtadmission between data.dtadmission and DATEADD(DD,6,data.dtadmission) 
where list.dtAdmission = '5-Jan-2011' 

상태에 가입 실제이 비교 목록 날짜 사이 방법 : 이것은 단지 하나의 listdate에 대한 가입 데카르트입니다 :

무슨 뜻인지보고, 다음을 시도하십시오 모든 레코드에서 datadate 및 dataplus6?

+0

예 하드 코딩 된 날짜 범위와 그 쿼리의 다른 몇 가지 사항은 실제 기능에 변수가 있지만 테스트 목적으로 만 사용되었습니다. 나는 이것을 밖으로 시험 할 것이다! – Mike

+0

6 일 이전 날짜와 오늘 날짜를 어떻게 설명 할 수 있습니까? 나는 그것이 그것을하는 것을 알고있다. 그러나 내가 그것을 볼 때 DATEADD 함수 때문에 플러스의 6 일인 것으로 간주한다 – Mike

+1

당신의 질문에 대답하여 대답을 편집했다 – user662852