web-dev-qa-db-ja.com

MySQL GROUP BYおよびHAVING

列Xに基づいて結果をグループ化し、グループ内で列Yの値が最も高い行を返します。

SELECT * 
FROM   mytable 
GROUP  BY col1 
HAVING col2 >= (SELECT MAX(col2) 
                FROM   mytable AS mytable2 
                WHERE  mytable2.col1 = mytable.col1 GROUP BY mytable2.col1) 

上記のクエリを最適化したいと思います。サブクエリなしで実行できますか?

私は解決策を見つけました、そしてあなたが考えるよりも簡単です:

SELECT * FROM (SELECT * FROM mytable ORDER BY col2 DESC) temp GROUP BY col1

20,000行で5ミリ秒で実行されます。

15
Elie

JOINの派生テーブル/インラインビューの使用:

SELECT x.* 
  FROM mytable x
  JOIN (SELECT t.col1,
               MAX(t.col2) AS max_col2
          FROM MYTABLE t
      GROUP BY t.col1) y ON y.col1 = x.col1
                        AND y.max_col2 >= x.col2

関連するxレコードが複数ある場合、これはyレコードを複製することに注意してください。重複を削除するには、DISTINCTを使用します。

SELECT DISTINCT x.* 
  FROM mytable x
  JOIN (SELECT t.col1,
               MAX(t.col2) AS max_col2
          FROM MYTABLE t
      GROUP BY t.col1) y ON y.col1 = x.col1
                        AND y.max_col2 >= x.col2

以下はテストされていませんが、重複を返しません(有効であると想定)。

SELECT x.* 
  FROM mytable x
 WHERE EXISTS (SELECT NULL
                 FROM MYTABLE y
                WHERE y.col1 = x.col1
             GROUP BY y.col1
               HAVING MAX(y.col2) >= x.col2)
13
OMG Ponies

Col2がMAX(col2)より大きくなることはないので、col2 = MAX(col2)を使用することをお勧めします

だからここはクエリです

SELECT * FROM  mytable GROUP BY col1 HAVING  col2 = MAX(  col2 ) 
1
Fisherman