2016-10-28 2 views
0

내가 해결할 수없는 PostgreSQL의 동적 평균 문제가 : 나는 시작과 개인에 대한 데이터를 가지고있는 고용 날짜를 완료재귀 포스트그레스 SQL 동적 평균

을 다음과 같이

"parentid"        "Name"    "startdate"  "enddate" 

"01e7de72-843d-4aa5-b3ae-2e2887d1b342" "Isabelle Smith"  "2011-05-23" "2016-04-16" 
"027ee658-8c4d-4910-b93e-62c0900f2147" "Emelie Blogs"  "2012-09-17" "2016-03-16" 
"02cbb478-adf3-4a8b-a5aa-ae9f03943ce4" "Joshauh Jow"   "2015-04-04" NULL 
"0328f382-2845-4623-a940-ab68af5d11cc" "VICTORIA Fred"  "2015-05-11" NULL 
"03823a20-51bc-4ae5-ab73-79056355ea36" "Elin Tree"   "2014-03-24" NULL 
"03878ef8-1c3a-4310-b3d5-7b8d18634707" "Michaela Apple"  "2011-07-08" NULL 
"03c36926-395b-4e3c-9f77-c6214ce763a2" "Immad Cheese"  "2012-05-15" NULL 
"0436824c-29a6-4140-ba4a-d0f56facd8fc" "Burak Teal"   "2009-06-22" NULL 
"04d7a07a-0ad4-4091-98d2-a7ff35798b6f" "Roberto Purple"  "2015-03-30" "2016-03-01" 
"04f32c2f-887f-4e03-be67-bc023aa3a7c2" "Iftikar Orange"  "2012-06-27" NULL 
"055b690a-153a-49c8-8ac0-112681f79551" "Josef Red"   "2014-02-21" "2016-04-13" 
"055be2f6-baec-4626-b876-7ff16dc95464" "Harry Green"   "2016-03-27" NULL 
"05a570b0-ec76-49d9-a742-5bf08f215fec" "Sofie Blue"   "2010-06-15" "2016-05-16" 
"05c92e7a-efde-44f0-a57c-298cbe129259" "BANARAS Yellow"  "2015-06-22" NULL 
"05fe0113-9bda-407b-bd72-5bf2a9deae15" "Bengt Drury"  "2015-03-30" "2016-06-16" 
"063c454f-2e97-48a8-96fc-9e84d29f5d96" "Son That"   "2016-03-27" NULL 
"07b76b47-8086-4df6-a3da-50dcfcd2de89" "Sam This"   "2015-03-21" "2016-05-24" 
"082771ee-2f02-4623-abc2-696447f9f791" "Felix This"   "2014-11-24" "2016-05-31" 
"08e39639-176b-4f44-ae75-1025219730c6" "ROBIN That"   "2015-10-26" NULL 
"09ab8491-9d9a-4091-b448-8315e3b5d3f0" "Kaziah This"   "2016-05-14" NULL 
"0a74dd0c-e1ee-4b32-a893-c486f7402363" "Luke Him"   "2015-12-16" NULL 
"0b098799-7d92-47df-9778-b48edf948af9" "MARIA Her"   "2015-05-11" NULL 
"0b480b25-8d2b-441b-8039-48b4e9188769" "That Adebayor"  "2015-04-09" NULL 
"0b86b44e-f3e0-4ddf-8e72-e0d7f9470279" "This Ålund"   "2012-02-07" "2016-06-05" 
"0c3e13d0-f602-41da-b10c-f70072605e63" "First Ekmark"  "2013-02-08" NULL 
"0d2367f4-a6b4-4381-b7dc-3e0c9063285f" "Anna Check"   "2015-03-13" NULL 
"0e31731b-0384-43ef-adeb-503ad5a137f9" "Assign Test1"  "2015-05-22" NULL 
"0e3f8b57-cba2-4240-abd4-d157832ef421" "Ramises Person  "2016-10-11" NULL 
"0f6af1c8-7672-4f0b-912c-91675cf52845" "Lars Surname"  "2016-03-28" NULL 

을이 보고서 사용자의 경우를 startOfPeriod와 endOfPeriod의 두 가지 날짜를 입력 할 것입니다.

동적 인 날짜에 대해 매주 그 기간 동안 고용 된 사람들의 수를 출력하는 SQL 문이 필요합니다. (1 주일은 startOfPeriod 날짜로부터 각각 7 일을 구성 할 것입니다.)

PostgreSQL에서 가능합니까? 어떻게해야합니까?

답변

1

아이디어는 시작일과 종료일 사이에 일련의 주를 생성하고 고용에서 시작일과 종료주를 선택한 다음 매주마다 계산합니다. 내가 바인딩 경우에 그것을 테스트하지했지만 뭔가 영업 coud가

WITH startDate(d) as (VALUES ('2010-01-01'::DATE)) 
    , endDate(d) as (VALUES ('2016-06-06'::DATE)) 
    , weeks as (select to_char(startDate.d+s.a,'YYYY-WW') as w 
       from startDate,endDate,generate_series(0,(endDate.d - startDate.d),7) as s(a)) 
    , emp as (select name,to_char(sd,'YYYY-WW') as sw 
         , to_char(coalesce(ed,endDate.d),'YYYY-WW') as ew 
      from startDate,endDate,public.so where sd > startDate.d) 
SELECT 
    w.w 
    ,(select ARRAY_AGG(name) from emp Where w.w BETWEEN sw AND ew) as emps 
    ,(select count(name) from emp Where w.w BETWEEN sw AND ew) as empCount 
FROM weeks w 

테스트 설정

create table public.so (
    name TEXT 
    ,sd DATE 
    ,ed DATE 
); 

INSERT INTO public.so (name,sd,ed) VALUES 
    ('a','2011-05-23','2016-04-16') 
    ,('b','2012-09-17','2016-03-16') 
    ,('c','2009-12-12',null) 
    ,('d','2015-03-30','2016-03-01') 
    ,('e','2012-06-27',null) 
    ,('f','2014-02-21','2016-04-13') 
    ,('g','2016-03-27',null) 
    ,('h','2010-06-15','2016-05-16') 
; 
+0

감사를 갈 .. –

2

사용 유형 daterangeoverlap operator && 시작한다.

WITH의 첫 번째 쿼리는 두 번째 주 일련의 생성 기간을 정의 :이 줄 것이다

with period(start_of_period, end_of_period) as (
    values ('2012-01-20'::date, '2012-02-15'::date) 
), 
weeks as (
    select daterange(d::date, d::date+ 7) a_week 
    from period, 
    lateral generate_series (start_of_period, end_of_period, '7d'::interval) d 
) 
select lower(a_week) start_of_week, count(*) 
from weeks 
left join a_table 
on daterange(startdate, enddate) && a_week 
group by 1 
order by 1; 

start_of_week | count 
---------------+------- 
2012-01-20 |  4 
2012-01-27 |  4 
2012-02-03 |  5 
2012-02-10 |  5 
(4 rows)  
+1

범위 생성자는 기본적으로 낮은 포괄적이고 독점적 인 상한을 사용합니다. 그래서'daterange (d :: date, d :: date + 7)'또는'daterange (d :: date, d :: date + 6, '[]')'중 하나가 필요합니다. 또한 범위를 제한 할 수 없으므로 무한 값을 제외하려는 경우를 제외하고 병합 ... 무한대 "해킹"을 사용할 필요가 없습니다. – pozs

+0

@pozs - 감사합니다. 쿼리가 수정되었습니다. – klin

+0

고마워요. 이거 드리겠습니다. –