人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

MySQL 5.1.30での質問です。Inner Joinで作ったテーブルから、重複したレコードの最新のものを取り出したいと思っています。まず、

Select A.a1, A.a2, A.a3, A.a4, B.b1, D.d1, D.d2, D.d3, D.d4, E.e1
From A Inner Join C On C.ID = A.`cID` Inner Join B On B.ID = C.`bID` Inner Join D On D.ID = B.`dID` Inner Join E On E.ID = D.`eID`
Order By C.ID

として内部結合したテーブルをC.IDでソートしました。ここで、C.IDで重複するレコードがあるためそれをグループ化して、A.a4の最大値を持つレコードをそれぞれのグループから取り出したく、下記を書きました。結果は、A.a4の最大値はそれぞれのグループから返ってくるものの、その他のカラムの値は、それぞれのグループの一番古いレコードでの値が返ってきます。Inner Joinしたテーブルから、Group Byを使って、カラムを丸ごと一つそれぞれのグループから持ってくることは不可能なのでしょうか?ご回答よろしくお願い致します!

Select A.a1, A.a2, A.a3, MAX(A.a4), B.b1, D.d1, D.d2, D.d3, D.d4, E.e1
From A Inner Join C On C.ID = A.`cID` Inner Join B On B.ID = C.`bID` Inner Join D On D.ID = B.`dID` Inner Join E On E.ID = D.`eID`
Group By C.ID
Order By C.ID

●質問者: fsv0109
●カテゴリ:インターネット ウェブ制作
✍キーワード:A1 A3 CID D1 D2
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● ふるるP
●35ポイント

MySQL は使ったことがないのですが、SQLとして。

Select T2.*

From

(

Select C.ID as C_ID , Max(A.a4) as mA_a4

From A Inner Join C On C.ID = A.`cID`

Inner Join B On B.ID = C.`bID`

Inner Join D On D.ID = B.`dID`

Inner Join E On E.ID = D.`eID`

Group By C.ID

) T1 Inner Join

(Select C.ID as C_ID, A.a1, A.a2, A.a3, A.a4 as A_a4, B.b1, D.d1, D.d2, D.d3, D.d4, E.e1

From A Inner Join C On C.ID = A.`cID`

Inner Join B On B.ID = C.`bID`

Inner Join D On D.ID = B.`dID`

Inner Join E On E.ID = D.`eID`

) T2

ON T2.C_ID = T1.C_ID

AND T2.A_a4 = T1.mA_a4

のようになるかと思います。肝はキーとなるものだけで一旦仮想表を作り、そのキーに対してもとの仮想表を結合させること。

今回のでしたら、

Select C.ID, A.a1, A.a2, A.a3, A.a4, B.b1, D.d1, D.d2, D.d3, D.d4, E.e1

From A Inner Join C On C.ID = A.`cID` Inner Join B On B.ID = C.`bID` Inner Join D On D.ID = B.`dID` Inner Join E On E.ID = D.`eID`

というビュー(vTemp)を作っておくとわかりやすくなるでしょう。各列には別名をつけておくと見やすくなります。グループ化するためのC.IDを出力の列に含ませておくこと。

すると、

From (Select C_ID, Max(A.a4) as MA4 From vTemp Group by A.a4) T1

Inner Join vTemp T2

On T1.C_ID=T2.C_ID AND T1.MA4

のようになって見やすくなります。

あと、もしかして「一番古いレコードの値」って、A1,A2,A3 のみですか?

であるなら、Aについてだけ、A.cIDでグループ化してMax(A4)と一致する行を取り出せばよさそうです。


2 ● chuken_kenkou
●35ポイント

まず、SQLとして誤った使い方をしています。


(1)標準SQLや主要なRDBMS、MySQLでも許されるSQL

SELECT c1,c2,max(c3),min(c4)
 FROM t1
 GROUP BY c1,c2

(2)標準SQLや主要なRDBMSでは許されないが、MySQLでは許されるSQL

SELECT c1,c2,c4,c5,max(c3),min(c4)
 FROM t1
 GROUP BY c1,c2

MySQL :: MySQL 4.1 リファレンスマニュアル :: 6.3.7.3 非表示のフィールドに対する GROUP BY


標準SQLや主要なRDBMSで、GROUP BY指定時、SELECTの選択列に指定できるのは、

だけです。

MySQLでは、この部分に独自仕様を持っていて、

としています。



Select A.a1, A.a2, A.a3, MAX(A.a4), B.b1, D.d1, D.d2, D.d3, D.d4, E.e1

・・・中略・・・

Group By C.ID

この使い方では、GROUP BY C.IDで、

A.a1, A.a2, A.a3,B.b1, D.d1, D.d2, D.d3, D.d4, E.e1

も一意にならなければ、結果を保証されません。


また、MAX(A.a4)の値を持つ行を得たいなら、サブクエリでa4の値がMAX(A.a4)のものを検索するといったことをしなければ、MAX(A.a4)を持つa4の行を得ることはできません


ところで、どの列で、行を一意に識別できるのでしょうか?

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ