2016-07-01 8 views
1

年と月を含む変数、つまり2016-07をmysqlに渡して週の日付範囲を表示したいのですがどうすれば達成できますか:: -07その後、私の出力は次のようになります。mysqlを使用している特定の月の週の範囲

2016-07-03 to 2016-07-10 || 2016-07-11 to 2016-07-17 

ので

+0

最初の日付を07の最初の日曜日にし、最後の日付を07の最後の日曜日にしますか? –

+0

いいえ、私はまた、すべての週の範囲をalso.let私の間に明確にしたい。私が5月に欲しいなら、その月と年の週の範囲は次のようになります:2016-05-01 to 2016-05-07 || 2016-05-08〜2016-05-14 || 2016-05-15 to 2016-05-21 || 2016-05-22〜2016-05-28 || 2016-05-29〜2016-06-04 –

+0

2016-07に合格すると、最初の日付は2016-07-03となりますか?最後の日のルールは何ですか? –

答えて

0

にはMySQLでそれを解決するために行くとき、この問題を解決するためのいくつかの部分があります。

1つは、あなたの週が日曜日か月曜日かを決定することです。これはロケール固有のビジネスルールです。以前は大英帝国(アメリカ、インド)に所在していたロケールでは、通常は日曜日です。他の場所では、月曜日です。

したがって、次のような関数が必要です。firstDayOfWeek(date)それについての詳細はすぐに分かります。

これを取得したら、問題の月の最終日を取得する方法が必要になります。それは簡単です;それはbuilt-in MySQL function. LAST_DAY(date)

1941-12のような文字列で問題の月を指定すると言いました。これをDATEオブジェクトに変換する必要があります。それは次のように行うことができます。

STR_TO_DATE(CONCAT(`1941-12`, `-01'), '%Y-%m-%d') 

我々はのは、そのテーブルseq_0_to_4を呼ぶことにしましょう0から4までの整数で仮想テーブルを必要としています。月が5日以上(月曜日)を超えないため、この範囲の整数を選択します。それについては後で詳しく説明します。

これは概念的なビルディングブロックです。それらを使ってみましょう。月の最後の日由来週の

初日は

SET @month := '1941-12'; 
SET @first_day_of_month := STR_TO_DATE(CONCAT(`1941-12`, `-01'), '%Y-%m-%d') 
SET @seed : =FirstDayOfWeek(LAST_DAY(first_day_of_month)); 

です次に、あなたが@seedされ、最後そのうち4 5週連続開始日が必要です。

 SELECT @seed - INTERVAL (7*seq.seq) first_day_of_week 
      FROM seq_0_to_4 

次に、月の日数に制限する必要があります。

SELECT first_day_of_week, 
     first_day_of_week + INTERVAL 6 DAY last_day_of_week 
    FROM (
     SELECT @seed - INTERVAL (7*seq.seq) first_day_of_week 
      FROM seq_0_to_4 
     ) w 
WHERE first_day_of_week >= @first_day_of_month 
ORDER BY first_day_of_week 

これは、1か月間に始まる週ごとに1つの行の表を提供します。

:あなたは最後の平日は、来月になっている週を除外したい場合は、あなたのWHERE最後

WHERE first_day_of_week >= @first_day_of_month 
    AND first_day_of_week + INTERVAL 6 DAY <= @seed 

、この中には、そのクエリをラップ、あなたの質問に指定された正確な文字列形式を取得するには変更

SELECT GROUP_CONCAT (
      CONCAT(first_day_of_week, ' to ', last_day_of_week) 
      SEPARATOR ' || ' 
      ORDER BY first_day_of_week) 
    FROM (
     SELECT first_day_of_week, 
       first_day_of_week + INTERVAL 6 DAY last_day_of_week 
      FROM (
       SELECT @seed - INTERVAL (7*seq.seq) first_day_of_week 
        FROM seq_0_to_4 
       ) w 
     WHERE first_day_of_week >= @first_day_of_month 
     ) x 

これだけです。

FirstDayOfWeek(dt)と約束しました。ここにあります。

 FROM_DAYS(TO_DAYS(dt) -MOD(TO_DAYS(dt) -1, 7)) 

これは少し魔法の呪文ですが、動作します。あなたの週が月曜日に始まるなら、それはこれです。

 FROM_DAYS(TO_DAYS(dt) -MOD(TO_DAYS(dt) -2, 7)) 

seq_0_to_4と約束しました。MySQLのMariaDBフォークを使用している場合は、それが組み込まれています.Sun/Oracleフォークを使用している場合は、このように定義します。一緒にすべてを置く

(SELECT 0 AS seq UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) seq_0_to_4 

SET @month := '1941-12'; 
SET @first_day_of_month := STR_TO_DATE(CONCAT(`1941-12`, `-01'), '%Y-%m-%d'); 
SET @seed := FROM_DAYS(TO_DAYS(LAST_DAY(first_day_of_month)) 
         -MOD(TO_DAYS(LAST_DAY(first_day_of_month)) -1, 7)); 
SELECT GROUP_CONCAT (
      CONCAT(first_day_of_week, ' to ', last_day_of_week) 
      SEPARATOR ' || ' 
      ORDER BY first_day_of_week) 
    FROM (
     SELECT first_day_of_week, 
       first_day_of_week + INTERVAL 6 DAY last_day_of_week 
      FROM (
       SELECT @seed - INTERVAL (7*seq.seq) first_day_of_week 
        FROM  (SELECT 0 AS seq UNION SELECT 1 UNION SELECT 2 
              UNION SELECT 3 UNION SELECT 4 
          ) seq 
       ) w 
     WHERE first_day_of_week >= @first_day_of_month 
     ) x 

を純粋なMySQLの方言SQLであなたの問題を解決するために不当に複雑な(専門用語ではfreakinの毛玉です)ですが、それは可能です。

+0

私はこれを提示しているので、SQLの日付計算の可能性を見ることができます。私はそれをデバッグしていない。私の希望は、それをあなたのプログラムに卸売りするだけでなく、あなたがそれから学び、あなたのものにすることです。 –

関連する問題