[pgsql-jp: 40631] JOINを書き直さなくても対応できるようにしたいのですが

yukihito miso mail @ rishiri.info
2010年 12月 18日 (土) 18:48:48 JST


?長文になりますが、よろしくお願いいたします。

年1回継続して行われている
マラソン競技の成績を記録・管理するデータベースですが
テーブルの構造をどのようにすればいいか悩んでいます。

5つのテーブルが有り、構造は以下のようなものです。

' TABLE users 選手マスタ
  u_id serial NOT NULL
  id integer NOT NULL
  first_name character varying
  last_name character varying
  first_phonetic character varying
  last_phonetic character varying
  age integer
  g_id integer
  postal_code character(8)
  address character varying
  n_id integer
  flg integer
  PRIMARY KEY (u_id)


' TABLE records 記録保存
  r_id serial NOT NULL
  id integer
  s_id integer
  results time without time zone
  flg integer
  time_stamp timestamp with time zone DEFAULT now()
  n_id integer
  PRIMARY KEY (r_id)

' TABLE sector 記録ポイントマスタ
  s_id serial NOT NULL
  sector character(6)
  notes character varying
  PRIMARY KEY (s_id)

' TABLE gender 性別マスタ
  g_id serial NOT NULL
  gender character(6)
  PRIMARY KEY (g_id)

' TABLE awards_lists 各賞の記録保存
  r_id serial NOT NULL
  id integer NOT NULL
  n_id integer
  award_name character varying
  PRIMARY KEY (r_id)


idが選手のゼッケン番号となっていて
s_idが各ポイントのキーで
n_idが開催回のキーです。

要件としては
(1)recordsのresultsがs_id分すべて入力されていてゴールポイント記録が10時間以内なら完走証を出力
(2)recordsのresultsがs_id分すべて入力されていなければ参加証を出力
(3)awards_listsの記録がある選手には別に対応する賞を出力
(4)リタイヤも記録する(ここはまだ実装できていません)

現在は、下記のような一覧表を作成するSQLで
usersとrecordsをid(選手のキー)とn_id(開催回のキー)でJOINして
さらに、s_id(各ポイントのキー)をポイントの数だけJOINして
一覧表示や賞状の出力を行うところまで出来ているのですが

このままだとポイントの数が開催回によって変動した時に
その分JOINを書き直さなければならないので
対応するようにできないものかと考えています。
どなたか、案がありましたらご指導ください。

' 一覧表を作成するSQL(一時テーブルの抜粋)
SELECT
u.u_id AS id
, u.first_name || (' ' || u.last_name) AS name
, u.first_phonetic || (' ' || u.last_phonetic) AS phonetic
, u.age AS age
, g.gender AS gender
, b.results AS s4
, c.results AS s9
, d.results AS sg
, n.n_id AS n_id
, n.number AS number
, al.award_name AS award_name
FROM users AS u
LEFT JOIN numbers AS n ON u.n_id = n.n_id
LEFT JOIN records AS b ON u.id = b.id AND b.s_id = 1 AND b.n_id = :n_id AND 
b.flg = 0
LEFT JOIN records AS c ON u.id = c.id AND c.s_id = 2 AND c.n_id = :n_id AND 
c.flg = 0
LEFT JOIN records AS d ON u.id = d.id AND d.s_id = 3 AND d.n_id = :n_id AND 
d.flg = 0
LEFT JOIN awards_lists AS al ON u.id = al.id AND al.n_id = :n_id
INNER JOIN gender AS g ON u.g_id = g.g_id
WHERE u.flg = 0
AND b.results <> '00:00:00'::TIME
OR c.results <> '00:00:00'::TIME
OR d.results <> '00:00:00'::TIME;




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