- PR -

カレンダテーブルからのデータ抽出

投稿者投稿内容
てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2004-10-08 12:14
てっくです。

いっそのことSQL×3に分けてみてはいかがでしょう?

  1. 開始年月に関するSELECT
  2. 開始と終了の間の年月に関するSELECT
  3. 終了年月に関するSELECT

例えば2002/12/20〜2004/03/05までの場合、
(こんな条件検索もありなんですか?)

  1. select 社員コード,年,月,... from 休暇テーブル where 年=2002 and 月=12 and (20日〜31日までのチェック)
  2. select 社員コード,年,月,... from 休暇テーブル where (2003/01〜2004/02までの条件) and (1日〜31日までのチェック)
  3. select 社員コード,年,月,... from 休暇テーブル where 年=2004 and 月=3 and (1日〜5日までのチェック)

とかですがー。

開始年月と終了年月のチェックに使う日付は動的にコテコテするとして、
その間のSELECTは一括で、と。
勿論3つのSQLをくっつけてしまってもいいんですが。

#ストアドにしてしまうのも手かもしれませんね。
#あ〜、でも下手をすれば常に全件検索になってしまうかも。。。ダメかな〜。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-10-08 12:32
OracleMasterでは設計能力を問わないから...

パフォーマンスを無視した設計なのでこの際パフォーマンスは無視して
判り易い、デバッグし易い(コーディング量を減らす)方が良いのでは?

つまり、
月の選択はSQLにて日の選択はVBでって事です。

一案として...




てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2004-10-08 12:44
実は
「社員一ヶ月分のデータを1レコードで管理したい」
というのがあったりして。

SELECT一発で(1レコードとして)取れるから。
引用:
月の選択はSQLにて日の選択はVBでって事です。


これだと開始年月と終了年月は全社員分のデータを
クライアントに転送した後でチェックするってことですよね?
ムダも多いかも。と思いましたが、いかがでしょう?
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-10-08 12:55
引用:

てっくさんの書き込み (2004-10-08 12:44) より:
引用:
月の選択はSQLにて日の選択はVBでって事です。


これだと開始年月と終了年月は全社員分のデータを
クライアントに転送した後でチェックするってことですよね?
ムダも多いかも。と思いましたが、いかがでしょう?


その無駄っていうのは人間的に云うと処理時間が掛かるって事ですよね?

もともとの設計思想にパフォーマンスが考慮されているとは思えないから、
設計思想が排除した事に対して実装で立ち向かってもね...という感じです。

で一点、
先ほどは軽めな提案だったので伺わなかったのですが

抽出条件に一致したレコードをその後どう利用するのですか?
単に該当の社員コードが欲しいだけ?
杏仁豆腐
常連さん
会議室デビュー日: 2003/10/04
投稿数: 48
お住まい・勤務地: あっち・なぜか平和だったところ(T_T)
投稿日時: 2004-10-08 13:11
こんなのどうでしょうか
テーブルを

SELECT 社員コード,
(年 * 100 + 月) 年月,
1日 * POWER(10, 0)
+ 2日 * POWER(10, 1)
+ 3日 * POWER(10, 2)

+ 31日 * POWER(10, 30) 休暇

のようにして、WHERE句は

1.WHERE 年月 = 開始年 * 100 + 開始月
AND 休暇 >= POWER(10, 開始日 - 1)
2.WHERE 年月 > 開始年 * 100 + 開始月
AND 年月 < 終了年 * 100 + 終了月
AND 休暇 > 0
3.WHERE 年月 = 終了年 * 100 + 終了月
AND 休暇 < POWER(10, 終了日 + 1)

でUNIONする。
で、WHERE句に計算があるのでかなり遅いと思います。
ファンクション索引とか張れば、そこそこ速くなるかも

実際に動かしたりしてないので条件の +-1 とか不等号
とか間違ってる可能性おおありです。
1つのアイディアだけってことでかんべんしてください。
ロン
会議室デビュー日: 2003/09/12
投稿数: 16
投稿日時: 2004-10-08 13:26
お世話になります。
ご返答ありがとうございます。

引用:

はにまるさんの書き込み (2004-10-08 12:55) より:

抽出条件に一致したレコードをその後どう利用するのですか?
単に該当の社員コードが欲しいだけ?




今回のSQLは副問合せ用なので、社員コードがとれればいいです。
こんなテーブル設計のせいで無駄な工数を取られているようで、
やるせないです。

引き続き、よろしくお願いします。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-10-08 13:46
引用:

ロンさんの書き込み (2004-10-08 13:26) より:
今回のSQLは副問合せ用なので、社員コードがとれればいいです。


抽出結果が抽出条件になるんですね、ならばVBで処理するのは駄目ですね。

私は、MechanicalLifeさんの案をお勧めします。
休暇フラグの2進数化加算で考えましたが
MechanicalLifeさんの方がデバッグし易い為、優れていると思います。

またあのPower関数の箇所をVBのループ文で生成すればソースも綺麗でしょう。

最後に一点だけ、
設計者に対してパフォーマンスに課題点がある事をお伝えしてから
対処される事をお勧め致します。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-10-08 14:02
もう一個あった、効果性が不明で且つ詳細の記述が面倒なので
端折って仕様検証もせずに概念だけを記述します。(←無責任)

<日数チェックをユーザ定義関数にて行う。>

コード:
function chk_hoge(年,月,1日,2日,〜,31日,開始日,終了日) return Boolean;



というユーザ定義関数を作って
内部で開始日と終了日を分解し「年,月,1日,2日,〜,31日」を判断して結果を返す。

コード:
select distinct 社員コード
from   休暇テーブル 
where  年月 between 開始月 and 終了月
and    chk_hoge(年,月,1日,2日,〜,31日,開始日,終了日)
;


※最初の条件は、予め不要なchk_hogeに該当するレコード処理を排除する。

パフォーマンスの程度は不明。

つ、、辛いね...

スキルアップ/キャリアアップ(JOB@IT)