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

回答の条件
  • 1人10回まで
  • 登録:2009/01/28 02:45:05
  • 終了:2009/02/04 02:50:02

回答(2件)

id:frkw2004 No.1

ふるるP回答回数192ベストアンサー獲得回数212009/01/28 16:17:59

ポイント35pt

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)と一致する行を取り出せばよさそうです。

id:chuken_kenkou No.2

chuken_kenkou回答回数722ベストアンサー獲得回数542009/01/28 17:08:47

ポイント35pt

まず、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の選択列に指定できるのは、

  • GROUP BYで指定した列
  • COUNT、MAX、MINなどの集合(集計)関数
  • 定数

だけです。

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

  • GROUP BYにより一意になるなら、その列をSELECTで指定してもよい。しかし、一意にならないなら、エラーにはしないが、結果を保証しない

としています。



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の行を得ることはできません


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

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません