- PR -

複数テーブルのjoin

投稿者投稿内容
常連さん
会議室デビュー日: 2004/05/19
投稿数: 22
投稿日時: 2004-07-14 19:25
はじめまして、複数テーブルの結合について教えてください。
親テーブルOYATの子テーブルとしてMENT、FEMTがあり、OYATとMENT OYATとFEMTは1対Nの関係であるとします。

OYAT[CODE,KNAM]
MENT[CODE,SEQN,CHILD]
FEMT[CODE,SEQN,CHILD]

OYAT 1 <> N MENT (CODE)
OYAT 1 <> N FEMT (CODE)

このテーブル同士をリンクさせ、次のようなレコードを作成する結合方法はありますか。

OYAT A1[1,KAWASAKI]
MENT B1[1,1,TAROU] B2[1,2,HIDEKI] B3[1,3,KENJI]
FEMT C1[1,1,HANAKO] C2[1,2,SACHIKO]


A1-B1-C1
A1-B2-C2
A1-B3-NULL

OYATの子レコード数テーブル(CHIT)のようなものを作成して、常にMENTもしくはFEMTの最大レコード数と同一のレコードを保持しておき

CHIT[CODE,SEQN]
CHIT D1[1,1] D2[1,2] D3[1,3]


(((OYAT AS Oyat LEFT JOIN CHIT AS Chit ON Oyat.CODE = CHIT.CODE)
LEFT JOIN MENT AS Ment ON Chiy.CODE = MENT.CODE
AND Chit.SEQN = MENT.SEQN)
LEFT JOIN FEMT AS Femt ON Chiy.CODE = FEMT.CODE
AND Chit.SEQN = FEMT.SEQN)

A1-D1-B1-C1
A1-D2-B2-C2
A1-D3-B3-NULL


という方法も考えたのですが、レコードのメンテナンスが複雑になるので躊躇しています。
どなたかもっと簡単な方法をご存知の方よろしくおねがいします
カニ
ベテラン
会議室デビュー日: 2004/06/24
投稿数: 53
お住まい・勤務地: 横浜・川崎
投稿日時: 2004-07-14 22:05
・『OYATとMENT, OYATとFEMTは1対N』の N は 0 でも可?
・MENT と FEMT の関係は?
hama
会議室デビュー日: 2004/07/14
投稿数: 4
投稿日時: 2004-07-14 22:05
お疲れ様です。

以下の感じでどうでしょうか。

コード:
SELECT
  OYAT.KNAM,
  MENT.CHILD,
  FEMT.CHILD
FROM
  ((OYAT INNER JOIN MENT ON OYAT.CODE = MENT.CODE)
  LEFT JOIN FEMT ON (OYAT.CODE = FEMT.CODE)
  AND (MENT.SEQN = FEMT.SEQN))



SQL Server では、次の書き方も出来ます。

コード:
SELECT
  OYAT.KNAM,
  MENT.CHILD,
  FEMT.CHILD
FROM
  OYAT,
  MENT,
  FEMT
WHERE
      OYAT.CODE =  MENT.CODE
  AND OYAT.CODE *= FEMT.CODE
  AND MENT.SEQN *= FEMT.SEQN

常連さん
会議室デビュー日: 2004/05/19
投稿数: 22
投稿日時: 2004-07-15 09:38
書き込みありがとうございます。
引用:

hamaさんの書き込み (2004-07-14 22:05) より:
お疲れ様です。

以下の感じでどうでしょうか。

コード:
SELECT
  OYAT.KNAM,
  MENT.CHILD,
  FEMT.CHILD
FROM
  ((OYAT INNER JOIN MENT ON OYAT.CODE = MENT.CODE)
  LEFT JOIN FEMT ON (OYAT.CODE = FEMT.CODE)
  AND (MENT.SEQN = FEMT.SEQN))



SQL Server では、次の書き方も出来ます。

コード:
SELECT
  OYAT.KNAM,
  MENT.CHILD,
  FEMT.CHILD
FROM
  OYAT,
  MENT,
  FEMT
WHERE
      OYAT.CODE =  MENT.CODE
  AND OYAT.CODE *= FEMT.CODE
  AND MENT.SEQN *= FEMT.SEQN





これだと、MENTのレコードがFEMTのレコード分重複してしまいますね。
また、FEMTのレコード数がMENTのレコード数より多いときFEMTのレコードが取得できないですね。


引用:

カニさんの書き込み (2004-07-14 22:05) より:
・『OYATとMENT, OYATとFEMTは1対N』の N は 0 でも可?
・MENT と FEMT の関係は?



書き込みありがとうございます。
1対Nは0でも可です。
このテーブルは実際の業務とは別のものなのですが、
個人とその個人の子供(男)と子供(女)の関係を表しています。
レコードとしては男の子、もしくは女の子テーブルのレコード数の最大値で返ってきてほしいです。
少ないほうのテーブルのレコードはNULLでOKです。

昨日家で寝ながら考えてたんですけど、
SEQNテーブルとしてSEQbフとりうる範囲の最大値分のレコードを保持しておき、
常にそのSEQNテーブルと親テーブルの直積をとって、SEQNと子テーブル2つとLEFT JOIN
して、子テーブルのSEQN2つともNULLのレコード以外を取得する方法はどうでしょう。
これなら都度、SEQNの最大値分のレコードを保持しておく必要がないと思いました。
スピードは遅くなるのかな.....もっと良い方法があれば是非お願いします。
カニ
ベテラン
会議室デビュー日: 2004/06/24
投稿数: 53
お住まい・勤務地: 横浜・川崎
投稿日時: 2004-07-15 09:57
実行したわけではないので・・・

with
TMP as (
select
MENT.CODE as CODE
,MENT.SEQN as SEQN
from
MENT
union
select
FEMT.CODE as CODE
,FEMT.SEQN as SEQN
from
FEMT
)
select distinct
OYAT.CODE
,OYAT.KNAM
,TMP.SEQN
,MENT.CHILD
,FEMT.CHILD
from
(((
OYAT inner join TMP on OYAT.CODE = TMP.CODE)
left join MENT on TMP.CODE = MENT.CODE and TMP.SEQN = MENT.SEQN)
left join FEMT on TMP.CODE = FEMT.CODE and TMP.SEQN = FEMT.SEQN)
常連さん
会議室デビュー日: 2004/05/19
投稿数: 22
投稿日時: 2004-07-15 11:05
早速実行してみたのですが......
キーワード 'with' 付近に正しくない構文があります。
とエラーがでます。
何が問題なのでしょうか???

エラー原因は後で調べるとして、
UNIONで、SEQbフレコードが最大値分できることは確認しました。
別にテーブルを作成する必要がないので、この方法でやってみたいと思います。
どうもありがとうございました。

ところでdistinctなのですが、この場合重複削除の必要はありますか....
またまた、すいません。
カニ
ベテラン
会議室デビュー日: 2004/06/24
投稿数: 53
お住まい・勤務地: 横浜・川崎
投稿日時: 2004-07-15 11:13
引用:

鳥さんの書き込み (2004-07-15 11:05) より:
ところでdistinctなのですが、この場合重複削除の必要はありますか....
またまた、すいません。



TMP で重複しない?
常連さん
会議室デビュー日: 2004/05/19
投稿数: 22
投稿日時: 2004-07-15 11:40
UNIONでALLを指定していないので、重複していないかと思います。

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