- 締切済み
1ヶ月に土日は何日あるか
1ヶ月に土日は何日あるかをSQLで調べたいと思ってます。 指定した年月に土曜日が何回あるかがわかるような便利な関数はないでしょうか? 教えてください。
- みんなの回答 (9)
- 専門家の回答
みんなの回答
- choconamacream
- ベストアンサー率44% (152/338)
すいません、#8です。オリンピックを見ながらずっとカレンダーを眺めていたのですが、もっと簡略化できますね。 年間カレンダーとしては、#8にもあるとおり全部で14パターンですが、各月ごとのカレンダーのパターンは、つまるところ28パターンに全て集約できますね。 ある月の一日が日曜日で始まる場合、月曜日で始まる場合、・・・で、7パターン。それに加えて、閏年がある時も踏まえた上で、各月ごとのカレンダーの末日は28日、29日、30日、31日の4パターンのみです。よって、7×4より全部で28パターンですね。 で、土曜日の日数のみを表すテーブルを、以下のように作成します。(年間カレンダーより、規則的にこの様な結果になると思います。) \|28 29 30 31 ーーーーーーーーーー 日|4 4 4 4 月|4 4 4 4 火|4 4 4 4 水|4 4 4 4 木|4 4 4 5 金|4 4 5 5 土|4 5 5 5 上記のテーブルを元に、以下のような条件でSQL文を記述すれば、すぐに指定した年月に土曜日が何回あるかがわかることと思います。 列(属性)→LAST_DAY関数を用いて、各月の末日が4つのうちの何れかを求める。 行(組)→TO_CHAR関数を用いて、各月の一日が何曜日から始まるのかを求める。 ちなみに、日曜日の日数のみを表すテーブルは敢えて作成しないでおきますが、上記と同様にすればすぐに専用のテーブルを作成できることと思います。
- choconamacream
- ベストアンサー率44% (152/338)
OracleのSQLでは、ダイレクトにそのような処理をする関数が用意されていないため、一般的にはASPなどのプログラミング側で処理をすることになるかと思います。Javaなどであれば、恐らくコレクションなんかを用いるんじゃないかなあ、と。(PL/SQLに関しては、専門外なので割愛。) ただ、あくまでもSQLにこだわるのであれば、以下のようなアルゴリズムもあります。 そもそも、カレンダーというのは全部で14パターンあり、毎年そのどれかのパターンを繰り返し使用しているということになっています。 具体的には、元旦が月曜日の時、火曜日の時、・・・で、7パターン。それに、閏年の場合がそれぞれにありますから、×2で14ですね。(詳細については、「万年カレンダー」でググってみてください。) 今回の場合、インプットは「年」、「月」、「曜日」で、アウトプットが「日数」ですから、以下のようなテーブル2つ[SAT_DUAL],[SUN_DUAL]を事前に用意しておきます。 テーブル[SAT_DUAL] or [SUN_DUAL] 列(column)→1月、2月、3月、4月、5月、6月、7月、8月、9月、10月、11月、12月の12つ。 行(row)→「元旦_月」、・・・、「元旦_日」、「閏年_元旦_月」、・・・、「閏年_元旦_日」の14つ。 列の指定については、インプットの「月」をそのまま利用すればいいと思います。 行の指定については、インプットの「年」が4で割り切れるかで閏年かどうかを判断し、且つその「年」の元旦が何曜日なのかをOracleのTO_CHAR関数で求め、その結果をWHERE句に記述すればいいと思います。 もちろん、土・日両方の場合は、上記2テーブルの結果を足し算すればいいわけですね。 ちなみに、各テーブルのデータ(具体的な日数)については、以下のサイトなどを元に一つずつ入力しておいてください。(最初だけは、これが大変です。) 「万年カレンダー」 http://koyomi.vis.ne.jp/sub/cal_year.htm 以上、実際に試してはいませんがアドバイスということで。
- jamshid6
- ベストアンサー率88% (591/669)
いろいろな意見があって非常に興味深いですが、確かに1回きりの作業ならSQLではやらないでしょうね。ただ、DBプログラミング(PL/SQL)だったら、そういうニーズがあればDBサイドに欲しいと思うかもしれないなとは思います。 考え方は難しくなくて、TO_CHAR(日付,'d')で日曜を1とする番号が取得できますから、土曜、日曜がそれぞれ7番目に来るように日数を補った上で、7で割り、商を合計するだけです。 長いので関数にした方がいいでしょうが。。 指定した日の属する月の土日の数 CREATE OR REPLACE FUNCTION f_NUMHOL(P_DATE DATE) RETURN NUMBER AS BEGIN RETURN ( TRUNC( (TO_CHAR(LAST_DAY(P_DATE),'dd') +TO_CHAR(P_DATE-TO_CHAR(P_DATE,'dd')+1,'d')-1)/7,0) +TRUNC( (TO_CHAR(LAST_DAY(P_DATE),'dd') +MOD(TO_CHAR(P_DATE-TO_CHAR(P_DATE,'dd')+1,'d')+5,7))/7,0) ); END;
- don_go
- ベストアンサー率31% (336/1059)
1ヶ月に土日が何日あるかというのはデータベースの 内容によらずに一定なので、データベース処理を行う のが目的のSQLで処理をするのは一般的ではありません。 どうしても必要なのであれば、私なら年月と土日の数 から成るテーブルを作りますが?
- galluda
- ベストアンサー率35% (440/1242)
がるです。 えと…私が「奇異である」と感じたのは。 SQLは、本質的に「リレーショナルデータベースにおいて、データの操作や定義を行うための問い合わせ言語」なので。 基本的には「データの取得や格納をSQLで行い」「それらのデータをプログラム側で処理する」というのが、自然な流れになります。 無論、SQLでも「可能」ではあるのですが。 「可能」と「適切」の間には、深い隔たりがあるので。 もし、Cosmo2007さんが「趣味や個人的なもので」作成されているのであれば、それは個人の範疇だからよろしいと思うのですが。 もし業務でなさっているのであれば、現場の流儀等、特別な理由がないかぎり、そういった事はSQL(DB)側よりもプログラム(ビジネスロジック)側でやるほうがよろしいかと思われます。 以上、老婆心ではありますが。
- choconamacream
- ベストアンサー率44% (152/338)
遊び半分でいろいろとググっていたら、以下のサイトを発見。 OracleSQLパズル 5-18 期間内の特定の曜日の数を取得 http://oraclesqlpuzzle.hp.infoseek.co.jp/5-18.html ただし、私みたいに中学受験を経験していない者にとっては、「植木算」からの勉強が必要のようですね。
- Willyt
- ベストアンサー率25% (2858/11131)
そのような組み込み関数はないと思います。自分で作るよりないですよね。その場合、インプットしなければならない引き数は、月と1日の曜日の二つになります。7×4=28ですから、2月でも4回あり、7×5=35ですから、6回はないことになります。そこで5回あるかないかはその月が何曜で始まったかによることになります。2月は通常では4回、閏2月の場合は土曜で始まったときのみ5回、小の月では金曜 土曜で始まったときは5回、大の月では木曜、金曜、土曜で始まったときが5回となります。曜日を数字で表すことにすると割合簡単にルーチンが組めますよ。日曜はこれが一つずつ前進しますよね。
- DIooggooID
- ベストアンサー率27% (1730/6405)
その検索を行おうとしているデータベース上には、どのような項目が定義されているのでしょうか?
お礼
ご回答ありがとうございます。 >その検索を行おうとしているデータベース上には、どのような項目が定義されているのでしょうか? DBの項目は色々あるのですが、FROM dual で上手くできないかと思いまして…。
- galluda
- ベストアンサー率35% (440/1242)
がると申します。 えと…本質的には、そもそういう事をSQLでやる事自体が少々奇異であるように思われるのですが。 普通にプログラム上でやらない、あるいは出来ない理由などがあるのでしょうか?
お礼
ご回答ありがとうございます。 >えと…本質的には、そもそういう事をSQLでやる事自体が少々奇異であるように思われるのですが。 そうなのですか? >普通にプログラム上でやらない、あるいは出来ない理由などがあるのでしょうか? 出来ない理由はないです。 ただSQLでできるのなら、そのほうが便利かと思ったのです。
お礼
ご回答ありがとうございます。 >そのような組み込み関数はないと思います。 そうなんですか。 >自分で作るよりないですよね。 わかりました。 ゴリゴリ頑張ってみます。