- PR -

MySQLでの多重テーブル結合について

投稿者投稿内容
ブーレイ
会議室デビュー日: 2007/03/15
投稿数: 9
投稿日時: 2008-07-18 16:07
くまっちさん、有り難う御座います。

一足違い…@@;

IF文、使えるのですね…
それも試してみたいと思います。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-07-18 16:12
たぶんですが、こういうことですよね?
# 面倒なんで、e以降は省略
コード:

<baseテーブル>
id| ...
--+-----
1| ...
2| ...

<optionテーブル>
base_id|meta_key|meta_value
-------+--------+-----------
1| bbb|かきくけこ
1| ccc|さしすせそ
1| ddd|たちつてと
2| bbb|かかかかか
2| ccc|さささささ
2| ddd|たたたたた

<ほしい結果>
id| ... |m_bbb |m_ccc |m_ddd
--+-----+----------+----------+----------
1| ... |かきくけこ|さしすせそ|たちつてと
2| ... |かかかかか|さささささ|たたたたた



※ aaa が混じってたんで削除(。。;)

[ メッセージ編集済み 編集者: rain 編集日時 2008-07-18 16:15 ]
忠犬
大ベテラン
会議室デビュー日: 2006/05/01
投稿数: 109
投稿日時: 2008-07-18 16:20
case式の形式は、次の二つ。

形式1
コード:
case 列名
 when 値1 then 設定値1
 when 値2 then 設定値2
 [else 設定値n]
end 



形式2
コード:
case when 条件式1 then 設定値1
       when 条件式2 then 設定値2
 [else 設定値n]
end 



引用:

SELECT a.*,
CASE b.meta_key='bbb' THEN b.meta_value ELSE '0' END m_bbb,
CASE b.meta_key='ccc' THEN b.meta_value ELSE '9' END m_ccc,
〜中略〜
CASE b.meta_key='jjj' THEN b.meta_value ELSE '0' END m_jjj
FROM base AS a
INNER JOIN option AS b ON a.ID = b.base_id
WHERE a.type='xxx' ORDER BY a.sortnum ASC



つまり、形式2のwhenが抜けています。
ブーレイ
会議室デビュー日: 2007/03/15
投稿数: 9
投稿日時: 2008-07-20 00:26
レスが送れてすいません。

rainさん、そのとおりです。
忠犬さん、指摘有り難う御座います。


SELECT DISTINCT a.*,
CASE WHEN b.meta_key='bbb' THEN b.meta_value ELSE '0' END m_bbb,
CASE WHEN b.meta_key='ccc' THEN b.meta_value ELSE '9' END m_ccc,
〜中略〜
CASE WHEN b.meta_key='jjj' THEN b.meta_value ELSE '0' END m_jjj
FROM base AS a
INNER JOIN option AS b ON a.ID = b.base_id
WHERE a.type='xxx' ORDER BY a.sortnum ASC

上記の様な感じでとりあえず処理は出来たのですが、なぜか意図したものとは別に、一部が重複したレコードが出来てしまいます。

DISTINCT を付けたら少し減りましたが、各CASE処理したときのレコードがそのまま作成されてるような感じです。

OPTIONテーブルに重複データがあるかとも思い調べてみましたが、それも無いようですし、CASE式をIF式に変更して同じですし、なにか原因となることはありますでしょうか?
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-07-22 09:39
SQLはほぼ素人レベルなので詳しい方のフォローをお願いしたいところですが、
今回の場合はCASEでは無理なような気がします。

一応3通りの案を考えてみましたが、
1.カーニーさんの仰る通り、そのままでいく
2.baseテーブルとoptionテーブルのレコードを別々に取得して、プログラム側で加工する(ただしこれで早くなるかどうかは不明)
3.テーブル構成を見直してみる(ただし善し悪しだと思う)

現実的には1でいいんじゃないでしょうか。
くまっち
大ベテラン
会議室デビュー日: 2008/01/18
投稿数: 169
お住まい・勤務地: 茨城県のどこか。
投稿日時: 2008-07-22 11:27
一部が重複・・・だけでは、どこが重複してはいけないのか等わかりませんが
たぶんこういうことですかね?

コード:

SELECT
a.ID,
MAX(CASE WHEN b.meta_key='bbb' THEN b.meta_value ELSE '' END) m_bbb,
  〜中略〜
  MAX(CASE WHEN b.meta_key='jjj' THEN b.meta_value ELSE '' END) m_jjj
FROM
base AS a INNER JOIN "option" AS b ON a.ID = b.base_id
GROUP BY a.ID


(keyやテーブル制約など提示されていないので、的確な解は出せませんが)

[訂正]
SQLが崩れたので[CODE]により整形

[ メッセージ編集済み 編集者: くまっち 編集日時 2008-07-22 11:32 ]
ブーレイ
会議室デビュー日: 2007/03/15
投稿数: 9
投稿日時: 2008-07-22 13:57
rainさん、くまっちさん、レス有り難う御座います。

くまっちさんの教えて貰ったやり方でほぼ意図したものが取得出来ました。

CASE の ELSE を '' にするのがミソですかね…。

デフォルト値をELSEに設定していた場合、最大値(デフォルト値)を取得してしまって意図したレコードとして取得できなかったので^^;


以上、レスして下さった皆さん、有り難う御座いました。

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