2016-10-05 2 views
2

근무한 근로자와 개월이 있습니다. 어느 직원이 근무하지 않았는지 확인하고 싶습니다. 간단한 예를 고려해 그래프에서날짜 범위가 순차적인지 또는 범주 당 간격이 포함되어 있는지 확인하십시오.

enter image description here

를 그것은 다음과 같다 : enter image description here

원하는 결과는 다음

+-----------+-----+ 
| worker | gap | 
+-----------+-----+ 
| worker001 | 1 | 
+-----------+-----+ 
| worker002 | 1 | 
+-----------+-----+ 
| worker003 | 0 | 
+-----------+-----+ 

가정 :

  • 각 작업자는 시작일이 다를 수 있으며 다른 종료일은 입니다.
  • 표에는 근로자가 일 때의 날짜 (월) 만 포함됩니다.

나는 쿼리를 환영 하겠지만 어떻게해야 할 지 생각 만 해 주셔서 감사합니다. 내 생각은 다음과 같습니다.

각 작업자의 최소 및 최대 날짜를 확인하십시오. 각 근로자에 ​​대해 이틀 간의 순서를 생성하십시오 (모름). 원본 테이블에 가입하고 null이 있는지 확인하십시오. 그렇다면 우리는 공백이 있습니다.

+0

가 어떻게 'worker001'의 "1"의 값을받을 수 있나요을? 또한 사용중인 데이터베이스에 질문을 태그하십시오. –

+0

어떤 DBMS를 사용하고 있습니까? –

+0

알고리즘이 변경되면 작동해야합니까? – Nemeros

답변

3

A는 간격을 계산하는 아주 간단한 방법은 개월 수를 계산하고 최대 및 최소 사이의 차이를 살펴 보는 것입니다 :

select worker, 
     (datediff(month, min(month), max(month)) + 1) - count(*) as nummissing 
from t 
group by worker; 

참고 :이 달의 차이에 대한 SQL 서버 구문을 사용합니다; 그것은 단지 편의성이고 다른 대부분의 데이터베이스는 비슷한 기능을 가지고 있습니다.

+0

놀랍게도 간단하다 :-) –

+0

그러면 누락 된 근무 개월 수를 계산해야하며 간격 수는 계산하지 않아도됩니까? – Nemeros

+0

@Nemeros 질문에 나는 틈이있는 노동자 명단을 요구했다. 각 근로자는 낄낄 거 리거나하지 않습니다. 하지만 네가 맞습니다! 이 대답은 간격이 아니라 누락 된 달을 계산합니다. 내가 그것을 요구하지는 않았지만 틈새의 수가 많을 것이다. –

1

나는 일부 윈도우 함수 알고리즘을 사용할 것입니다.

입력 테스트 데이터 :

create table tt (key varchar(10), dte date); 

insert into tt values ('w1', '2017-12-01'); 
insert into tt values ('w1', '2017-11-01'); 
insert into tt values ('w1', '2015-12-01'); 
insert into tt values ('w1', '2015-11-01'); 
insert into tt values ('w1', '2016-01-01'); 
insert into tt values ('w1', '2016-02-01'); 
insert into tt values ('w1', '2016-05-01'); 
insert into tt values ('w1', '2016-06-01'); 
insert into tt values ('w2', '2016-02-01'); 
insert into tt values ('w2', '2016-03-01'); 
insert into tt values ('w2', '2016-05-01'); 
insert into tt values ('w3', '2016-01-01'); 
insert into tt values ('w3', '2016-02-01'); 

그런 다음 우리는 지속적인 작업 시간을 retreive하는 날짜 사이의 그룹을 만들려면 윈도우 함수를 사용합니다.

여기서부터는 표현식으로 다른 그룹과 함께 count - 1을 수행하면됩니다.

with tmp as (
select key, 
dte, 
dte - (row_number() over(partition by key order by dte) MONTHS) as rnk_month, 
row_number() over(partition by key order by dte) as rnk_tot 
from tt) 
select key, min(dte), max(dte), rnk_month 
from tmp 
group by key, rnk_month 
order by key, rnk_month 

sqlServer를 사용하여 쿼리 시도 구문 ...

기능 : ROW_NUMBER() (DTE에 의해 키 순서로 파티션) 이상이 outpout합니다

with tmp as (
select key, 
dte, 
dateadd(month, - row_number() over(partition by key order by dte), dte) as rnk_month, 
row_number() over(partition by key order by dte) as rnk_tot 
from tt) 
select key, min(dte), max(dte), rnk_month 
from tmp 
group by key, rnk_month 
order by key, rnk_month 

이 좀 더 설명하기 위해 (내가 SQL을이없는까지 확실하지가 작동합니다) 작업자 1 : 우리는 한 달에로 rnk_tot 고려 rnk_tot와 날짜를 빼지 경우 지금

----------------------------- 
Worker | Month  | rnk_tot 
----------------------------- 
w1  |2015-11-01 | 1 
w1  |2015-12-01 | 2 
w1  |2016-01-01 | 3 
w1  |2016-02-01 | 4 
w1  |2016-05-01 | 5 
w1  |2016-06-01 | 6 
w1  |2017-11-01 | 7 
w1  |2017-12-01 | 8 

, 우리는 몇 가지 연속 그룹을 형성 몇 가지 새로운 날짜가됩니다

---------------------------------------- 
Worker | Mth Min | Mth Max | rnk_month 
---------------------------------------- 
w1  |2015-11-01 |2016-02-01|2015-10-01 
w1  |2016-05-01 |2016-06-01|2015-12-01 
w1  |2017-11-01 |2017-12-01|2017-04-01 

를 그리고 여기에서 당신이 수를 할 수 있습니다 :

---------------------------------------- 
Worker | Month  | rnk_tot | rnk_month 
---------------------------------------- 
w1  |2015-11-01 | 1  |2015-10-01 
w1  |2015-12-01 | 2  |2015-10-01 
w1  |2016-01-01 | 3  |2015-10-01 
w1  |2016-02-01 | 4  |2015-10-01 
w1  |2016-05-01 | 5  |2015-12-01 
w1  |2016-06-01 | 6  |2015-12-01 
w1  |2017-11-01 | 7  |2017-04-01 
w1  |2017-12-01 | 8  |2017-04-01 

는 여기에서 (즉, 내가 게시 된 쿼리가하는 일입니다) 작업자 및 gatter 연속 작업 시간에 rnk_month 열에 의해 그룹을 할 수 틈새의. 그래서 최종 쿼리 수 :

내가 사용하는 테스트 케이스에 대한이 출력 줄 것이다
with tmp as (
select key, 
dateadd(month, - row_number() over(partition by key order by dte), dte) as rnk_month 
from tt) 
select key, count(distinct rnk_month) - 1 as gaps 
from tmp 
group by key 

:

----------------- 
Worker | Gaps 
----------------- 
w1  | 2 
w2  | 1 
w3  | 0 
+0

해당 코드에 약간의 오류가 있습니다. MONTHS라는 단어 근처. 적어도 SQL Server. 그 말은 무엇을 의미합니까? rnk_month 란 무엇입니까? –

+0

네, SQL을 사용하기 전에 db2를 사용했습니다. 기본적으로 rnk_month는 날짜입니다. 더 많은 답변을 청소기 설명 (내가 몇 가지 편집거야) – Nemeros

+0

sqls와 함께 작동합니다 두 번째 쿼리를 확인, 나는 쿼리의 주요 메커니즘을 explainend – Nemeros

관련 문제