2017-12-11 3 views
0

그래서 직장을 다니면 내 직원이 토요일을 교대로 작업합니다. 일부 직원은 매월 1 일 및 3 일 토요일에 근무하고 일부 직원은 매월 2 일 및 4 일 토요일에 근무하도록 배정됩니다.수학적으로 다섯 번째 토요일 찾기?

하나의 작은 문제가 발생합니다. 토요일이 다섯 개있는 해에는 4 개월이 있습니다. 일하기 쉬울만큼 쉬울 것 : 1/3 직원은 일년 중 제 1 및 제 3 토요일에 일하는 등등.

몇 년은 다섯 번째 토요일로 5 개월이 걸리지 만 지금은 그에 대해 이야기하지 않습니다. 나는, 서브 쿼리에서 날짜를 선택한 다음

select 
     curdate() - interval (a.a + (10 * b.a) + (100 * c.a)) day as Date 
    from (
     select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a 
     cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b 
     cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c 
     ) as a 

내 예약 테이블에 조인

어쨌든, 내가 먼저 날짜의 목록을 생성하려면 다음 코드를 사용하여 내 직원 스케줄을 생성하는 각 날짜에 각 직원의 작업 목록을 작성합니다.

다섯 번째 토요일이 추악한 머리를 뒤집을 때까지이 모든 작업이 잘됩니다. 지금이 순간, 나는 수학적는 올해 다섯 번째 어느 토요일 알아 내기 위해 다음 코드를 사용

mod(((datediff(date_add(a.date, interval (7-dayofweek(a.date)) day),date_add(subdate(a.Date,dayofyear(a.date-1)), interval (1-dayofweek(subdate(a.Date,dayofyear(a.date-1)))) day))+1)/7),4) 

또는 요약, 나는 현재 첫 번째 일요일부터 경과 일 수를 찾을 수 년을 이번주의 현재 토요일로 나누고 그것을 7로 나눈 다음 몇 토요일이 지난지를 계산 한 다음 4의 모듈로를 찾아 얼마나 많은 "추가"다섯 번째 토요일이지나 갔는지 알아 내십시오.

... 다섯 번째 토요일이 4의 배수 인 한주에 오지 않는 한이 코드는 완벽하게 미세하게 작동합니다. 고맙게도, 그것은 올해 전혀 일어나지 않지만 내년에는 이것을 처리 할 방법을 찾아야 할 것입니다.

주어진 다섯 번째 토요일이 매월 다섯 번째 토요일 중 어느 토요일인지를 수학적으로 파악하는 더 좋은 방법이 있습니까?

+0

당신이 실제로하는지 설명 할 수 SQL에서 출력하려고합니까? 나는 당신이 그걸로 무엇을 이루려고하는지 이해하지 못합니다. 이러한 종류의 계산은 * SQL *을 필요로하지 않지만 PHP와 같은 프로그래밍 언어로 수행해야하며 * 결과 *는 MySQL 데이터베이스에서 조작 할 수 있습니다. – Martin

+0

SQL은 데이터의 저장 및 검색을위한 것입니다. 내 생각으로는 다른 것을하기위한 시도는 실수입니다. – Strawberry

+0

이것의 출력은 정수, 1, 2, 3, 또는 4가 될 것입니다? WhichFifthSaturday가 삽입 되었습니까? 스케줄 테이블과의 조인에서 올바른 스케줄을 선택하는 데 사용되는 열. 또한 I * *이 다른 프로그래밍 언어를 사용하여이 작업을 할 수는 있지만 원하지 않습니다. 나는 SQL로 그것을하고 싶다. –

답변

0

오. 나는 이것의 SQL 조각을 overthinking 방법이었다. 실제로는 꽤 쉬웠습니다. 세 개의 임시 테이블을 만듭니다 하나를 완성 날짜 테이블을 개최, 다섯 번째 토요일을 한 기간에 대한 관심의 모든 날짜를 개최하고, 세 번째 표는 구체적으로 확인하는 방법은 다음과 같습니다

drop temporary table if exists DATES; 
create temporary table DATES (AdherenceDates date, WhichSaturday int, 
WhichFifthSaturday int); 
create temporary table DATES1 (AdherenceDates date, WhichSaturday int); 
create temporary table DATES2 (FifthSaturdayDates date, WhichFifthSaturday 
int auto_increment, primary key (WhichFifthSaturday)); 
insert into DATES1 (AdherenceDates, WhichSaturday) 
select 
a.Date as AdherenceDates, 
case 
    when day(adddate(a.date,(7-dayofweek(a.date)))) <= 7 
     then 1 
    when day(adddate(a.date,(7-dayofweek(a.date)))) <= 14 
     then 2  
    when day(adddate(a.date,(7-dayofweek(a.date)))) <= 21 
     then 3 
    when day(adddate(a.date,(7-dayofweek(a.date)))) <= 28 
     then 4 
    when day(adddate(a.date,(7-dayofweek(a.date)))) > 28 
     then 5 
end as WhichSaturday 
from 
(select 
    curdate() - interval (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a)) day 
as Date 
from ( 
    select 0 as a union all select 1 union all select 2 union all select 3 
union all select 4 union all select 5 union all select 6 union all select 7 
union all select 8 union all select 9) as a 
    cross join (select 0 as a union all select 1 union all select 2 union 
all select 3 union all select 4 union all select 5 union all select 6 union 
all select 7 union all select 8 union all select 9) as b 
    cross join (select 0 as a union all select 1 union all select 2 union 
all select 3 union all select 4 union all select 5 union all select 6 union 
all select 7 union all select 8 union all select 9) as c 
    cross join (select 0 as a union all select 1 union all select 2 union 
all select 3 union all select 4 union all select 5 union all select 6 union 
all select 7 union all select 8 union all select 9) as d 
    ) as a 
where dayofweek(a.Date) <> 1 
and a.Date >= '2017-01-01' 
order by a.Date asc 
; 
insert into DATES2 (FifthSaturdayDates) 
select 
a.Date as AdherenceDates 
from 
(select 
    curdate() - interval (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a)) day 
as Date 
from ( 
    select 0 as a union all select 1 union all select 2 union all select 3 
union all select 4 union all select 5 union all select 6 union all select 7 
union all select 8 union all select 9) as a 
    cross join (select 0 as a union all select 1 union all select 2 union 
all select 3 union all select 4 union all select 5 union all select 6 union 
all select 7 union all select 8 union all select 9) as b 
    cross join (select 0 as a union all select 1 union all select 2 union 
all select 3 union all select 4 union all select 5 union all select 6 union 
all select 7 union all select 8 union all select 9) as c 
    cross join (select 0 as a union all select 1 union all select 2 union 
all select 3 union all select 4 union all select 5 union all select 6 union 
all select 7 union all select 8 union all select 9) as d 
    ) as a 
where dayofweek(a.Date) = 7 
and a.Date >= '2017-01-01' 
and day(a.Date) > 28 
order by a.date asc; 
insert into DATES (AdherenceDates, WhichSaturday, WhichFifthSaturday) 
select 
DATES1.AdherenceDates, 
DATES1.WhichSaturday, 
DATES2.WhichFifthSaturday 
from 
DATES1 
left join 
DATES2 
on DATES1.AdherenceDates = DATES2.FifthSaturdayDates; 
drop temporary tables DATES1, DATES2; 
select * from DATES 
order by AdherenceDates asc; 
관련 문제