2009-04-24 6 views
9

私は、mysqlクエリーで月の週を取るための簡単な関数を探していました。私がいたとまで来ることができましたmysqlの月の週の機能

最高:

WEEK(dateField) - WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField)-1 DAY)) + 1 

私はここに車輪の再発明てるかどうかを知るのが大好きですし、簡単かつクリーンな解決策があるかどうか?

答えて

12

AFAIK、月の最初の週には標準がありません。

週の第1週は、Jan 4thを含む週です。

月の最初の週はどのように定義しますか?

UPDATE:年間の遷移は正しく処理、および週はMondayに開始されるように

SELECT WEEK(dateField, 5) - 
     WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField) - 1 DAY), 5) + 1 

あなたはこのようなあなたのクエリを書き直す必要があります。

それ以外の場合、クエリは正常です。

+0

私はそれが最も一般的な解決策ではないかもしれないと思うが、週が必要なものは月曜日に始まる。だから、月の1日が日曜日になると、日曜日は1週としてカウントされます。 – YiSh

8

レポートデータベースでは時々使用される代替方法があります。テーブルを作成し、それをALMANACと呼びましょう。日付(キー)ごとに1つの行があり、レポートの目的に役立つ可能性のある日付のすべての属性があります。

月の列の週に加えて、日付が会社の休日であるかどうかを示す欄があります。あなたの会社が7月またはその他の月に開始する会計年度を持っていた場合は、各日付が属している会計年度、会計月、会計年度などを含めることができます。

次に、入力する日付の範囲を考慮して、この表を薄い空気から埋めるプログラムを作成します。このプログラムには、すべてのクレイジーカレンダーの計算が1回だけ含まれています。

次に、他のテーブルの日付の属性を知る必要がある場合は、結合を行い、その列を使用します。はい、もう一度参加します。そして、いいえ、この表は正規化されていません。しかし、それはまだ特定の非常に特定のニーズのための良い設計です。

0

1週間のソリューションは日曜日に開始されます。

SELECT (1 + ((DATE_FORMAT(DATE_ADD(LAST_DAY(DATE_ADD('2014-07-17', 
    INTERVAL -1 MONTH)), INTERVAL 1 DAY),'%w')+1) + 
    (DATE_FORMAT('2014-07-17', '%d')-2)) DIV 7) "week_of_month"; 
1

(ただ、将来の読者のために明確にする:この古い質問にこの答えが原因で、現在の答えは満足ではなかった暗黙の奨励金を加えたので、私は追加して、このソリューション/定義を追加しましたあらゆる種類の状況に対応する「設定オプション」。)

ありWeek of monthのための標準的な定義はありませんが、一般的な解決策は、あなたのニーズに形作ることができ、次式のようになります。

  • "weekday_startofweek"がなければならない
    select (dayofmonth(dateField) + 6 + (7 - "min_days_for_partial_week") 
         - (weekday(datefield) - "weekday_startofweek" + 7) MOD 7) DIV 7 as week_of_month; 
    

    週の最初の曜日になりたい曜日に置き換えられます(0 = Monday6 = Sunday)。

  • "min_days_for_partial_week"は、第1週が第1週としてカウントされなければならない日数です(値17)。一般的な値は1(月の最初の日は常に1週目)、4(これは "iso week of the year"と似ています。ここで、年の最初の週は木曜日を含む週です。少なくとも4日)および7(週1は最初の完全な週である)。

この式では、値06が返されます。

0は、現在の週が週1としてカウントするのに十分な日を持っていない、とあなたが3日未満と部分的に数週間は1

例週ことを可能にするとき6にのみ起こることができる部分週間であることを意味し

週の最初の日は月曜日("weekday_startofweek" = 0)で、週1は、常に全体の週("min_days_for_partial_week" = 7)する必要がある場合、これは

select (dayofmonth(dateField) + 6 - weekday(datefield)) DIV 7 as week_of_month; 

例:に簡略化されます、2016-06-02のためにあなたは0を取得します、6月なぜなら2016年は水曜日から始まりました(Yと2016-06-06のために、あなたは、週の最初の日は必ず週1("min_days_for_partial_week" = 1)である、あなたの式を、エミュレートするために6月2016

で、これは最初の月曜日であることから、1を取得します、そして週は日曜日から始まります"weekday_startofweek" = 6あなたの定数から来た2年後に知って適切にそれをコメントしたいかもしれませんが)、これは

select (dayofmonth(dateField) + 12 - (weekday(datefield) + 1) MOD 7) DIV 7 as week_of_month; 

になります。

関連する問題