2017-12-11 13 views
0

私が働くところでは、私の従業員は土曜日に交互に働いています:一部の従業員は毎月の第1土曜日と第3土曜日に働き、一部は毎月第2土曜日と第4土曜日に働きます。数学的に5番目の土曜日を見つける?

1つの小さな問題が発生します.5つの土曜日がある年に4ヶ月があります。これは簡単に回避できます。第1 /第3従業員は、第1と第3の土曜日を第1土曜日などに働きます。

いくつかの年は5番目の土曜日で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 

を、私はサブクエリから日付を選択して、私のスケジュール表にそれらを結合します各日付ごとに各従業員の作業リストを作成します。

5番目の土曜日が醜いヘッドを裏返すまで、このすべてはうまく機能します。現時点では、私は数学的にそれが今年の第五のどの土曜日把握するには、次のコードを使用します。

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のモジュロを見つけて何回 "余分な"第5土曜日が過ぎたかを調べる。

...第4土曜日が4の倍数になると、このコードは完全に正常に動作します。ありがたいことに、それは今年も起こることはありませんが、来年はこれに対処する方法を理解する必要があります。

与えられた5番目の土曜日の月の5番目の土曜日を数学的に把握するには、より良い方法がありますか?

+0

を、あなたが実際にしているものを説明することができますSQLから出力しようとしていますか?私はあなたがそれで達成しようとしていることを理解していません。このような計算は* SQL *とは思えませんが、PHPなどのプログラミング言語で行う必要があります。この結果をMySQLデータベースで操作することができます。 – Martin

+0

SQLは、データの格納と検索用です。私の考えでは、他の何かをしようとするのは間違いです。 – Strawberry

+0

これの出力は、1,2,3、または4の整数で、WhichFifthSaturdayが挿入されます。スケジューリングテーブルとの私の加入時に、正しいスケジュールを選択するために使用される列。また、私はこれを操作するために別のプログラミング言語を使用することもできますが、私はしたくありません。私はSQLでそれをやりたい –

答えて

0

ああ男。私はこれのSQL部分を考えすぎた。実際にはかなり簡単でした。 1 1は、特に第五土曜日を見つけるためにあなたの期間の関心のすべての日付、および第三のテーブルを保持するために、完成した日付のテーブルを保持する:3の一時テーブルを作成

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; 
関連する問題