[pgsql-jp: 35493] Re: 2つのテーブルの比較と優先抽出

Hiroshi Ishiura issy777 @ e-entrance.org
2005年 6月 11日 (土) 23:21:24 JST


石浦です。

返信ありがとうございます。

> 久我と申します.
> 
> 石浦さん:
> 
>   >共通(曜日)単位の共通テーブルと日毎単位の個別テーブルがあり
>   >たとえば次のデータがあるとします
>   >
>   >共通料金帯テーブルA (charge_dayは曜日)
>   > planid | charge_day | charge1 | charge2 | charge3 | 
>   >--------+------------+---------+---------+---------+
> (略)
>   >日毎料金帯テーブル(charge_dayは日)
>   > planid | charge_day | charge1 | charge2 | charge3 | 
>   >--------+------------+---------+---------+---------+
> (略)
> 
> ``共通料金帯テーブルA''から``日毎料金帯テーブル''に存在するプランを
> 除いたものは
> 
> select * from 共通料金帯テーブルA
>     where planid not in (
> 	    select planid from 日毎料金帯テーブル
>             )
> ;
> 
> で得られますから,これと日毎料金帯テーブルを
> union すれば求めるものが得られると思います.

先ほどML投稿したあとに引き続き試行錯誤していたら今久我さんが書いていた
だいた方法とまったく同じ方法が考えついて自力でできたころにこのメールをみ
て同じ手法だったのでびっくりです^^

下部にかいてくださったSQL文でextract(dow from day)とタイムスタンプか
ら曜日をとっていますが、実はわかりやすい例として曜日としていたんですが、
実際は曜日種類テーブルが
平日=1、休前日=2、休日=3、特別日=4
などというようにあり

また別のカレンダーテーブルで
2005-06-11	2
2005-06-12	3
2005-06-13	1
などというように格納してあり

共通料金帯テーブルA (charge_dayは日タイプ)
planid | charge_day | charge1 | charge2 | charge3 | 
-------+------------+---------+---------+---------+
 001   |      1     |    4000 |    6000 |    8000 | 
 001   |      2     |    4000 |    6000 |    8000 | 
 001   |      3     |    4000 |    6000 |    8000 | 
charge_dayに平日料金(1)、休前日料金(2)、休日料金(3)
というかんじでテーブルがある状態なのです。

ですのでcharge_dayは本題のSQL文を発行するまえに指定日からcharge_dayを
決定し変数にいれておいてあります。

よって久我さんのSQLをちょっとおきかえると

> select * from (
>     select planid, charge1, charge2, charge3 from 日毎料金帯テーブル
>     	where charge_day = '2005-06-11'
>     union
>     select planid, charge1, charge2, charge3 from 共通料金帯テーブル
>     	where charge_day = '2'
>     	and planid not in (
> 	    select planid from 日毎料金帯テーブル
> 	    	where charge_day = '2005-06-11'
>             )
>     )  as tmp
> where charge1 > 0 or charge2 > 0 or charge3 > 0

こんなかんじで。

以外とこういう処理の場面はよくよく考えると結構ありそうですし使えますね。
よい機会でした。

ありがとうございました。


> 例えば以下によって
> 
>  planid | charge1 | charge2 | charge3 
> --------+---------+---------+---------
>  001    |    4000 |    5000 |    7000
>  003    |       0 |    4000 |    5000
> (2 rows)
> 
> となります(今後数時間のうちは ;).
> 
> ご質問の中で部分的に主旨が読みきれない箇所があったため
> 自信がないのですが,お求めなのはこうしたことでしょうか.
> 
> -----
> オフィス・リテロ
> 	久我 力
> 
> =====
> 
> create temp table dow_rate_tbl (
>     planid varchar,
>     day_of_week int,
>     charge1 int,
>     charge2 int,
>     charge3 int
> );
> 
> create temp table day_rate_tbl (
>     planid varchar,
>     day date,
>     charge1 int,
>     charge2 int,
>     charge3 int
> );
> 
> insert into dow_rate_tbl values('001', 6, 4000, 6000, 8000);
> insert into dow_rate_tbl values('002', 6, 0, 8000, 0);
> insert into dow_rate_tbl values('003', 6, 0, 4000, 5000);
> insert into dow_rate_tbl values('005', 6, 0, 0, 0);
> 
> insert into day_rate_tbl values('001', '2005-06-11', 4000, 5000, 7000);
> insert into day_rate_tbl values('002', '2005-06-11', 0, 0, 0);
> 
> select * from (
>     select planid, charge1, charge2, charge3 from day_rate_tbl
>     	where extract(dow from day) = extract(dow from current_date)
>     union
>     select planid, charge1, charge2, charge3 from dow_rate_tbl
>     	where day_of_week = extract(dow from current_date)
>     	and planid not in (
> 	    select planid from day_rate_tbl
> 	    	where extract(dow from day) = extract(dow from current_date)
>             )
>     )  as tmp
> where charge1 > 0 or charge2 > 0 or charge3 > 0
> ;
> 
> =====
> 
> 

-- 
Hiroshi Ishiura <issy777 @ e-entrance.org>





pgsql-jp メーリングリストの案内