推奨:MAX関数とGROUP BY文で使用されるエラー
7541 ワード
MAX関数やGROUPを使うと予想外のデータがSELECTされます.
簡単な例を示します.
SCOREIDごとに数学の成績が一番高い点数を知りたいです.
テーブル情報:
/*DDL Information For - test.lkscore*/
--------------------------------------
Table Create Table
------- -----------------------------------------------------------------------------
lkscore CREATE TABLE `lkscore` (
`scoreid` int(11) DEFAULT NULL,
`chinese` int(11) DEFAULT '0',
`math` int(11) DEFAULT '0',
KEY `fk_class` (`scoreid`),
CONSTRAINT `fk_class` FOREIGN KEY (`scoreid`) REFERENCES `lkclass` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312
select * from lkscore;
query result(12 records)
scoreid
chinese
math
1
90
80
2
100
99
3
29
98
4
87
79
5
89
99
1
49
98
3
98
56
2
76
88
2
80
90
3
90
70
1
90
90
1
67
90
エラーSELECT
select scoreid,chinese,max(math) max_math from lkscore group by scoreid;
query result(5 records)
scoreid
chinese
max_math
1
90
98
2
100
99
3
29
98
4
87
79
5
89
99
上の90は明らかに間違っています.
方法1:
select scoreid,chinese,math max_math from
(
select * from lkscore order by math desc
) T
group by scoreid;
query result(5 records)
scoreid
chinese
max_math
1
49
98
2
100
99
3
29
98
4
87
79
5
89
99
方法2:
select * from lkscore a where a.math = (select max(math) from lkscore where scoreid = a.scoreid) order by scoreid asc;
query result(5 records)
scoreid
chinese
max_math
1
49
98
2
100
99
3
29
98
4
87
79
5
89
99
これもMAX関数を使用しており、関連サブクエリも使用されています.
この2つの効率を見てみましょう.
explain
select scoreid,chinese,math max_math from (select * from lkscore order by math desc) T group by scoreid;
query result(2 records)
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
PRIMARY
ALL
(NULL)
(NULL)
(NULL)
(NULL)
12
Using temporary; Using filesort
2
DERIVED
lkscore
ALL
(NULL)
(NULL)
(NULL)
(NULL)
12
Using filesort
明らかに、FULL TABLE SCANが2つあります.
explain
select scoreid,chinese,math max_math from lkscore a where a.math =
(select max(math) from lkscore where scoreid = a.scoreid) order by scoreid asc;
query result(2 records)
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
PRIMARY
a
index
(NULL)
fk_class
5
(NULL)
12
Using where
2
DEPENDENT SUBQUERY
lkscore
ref
fk_class
fk_class
5
a.scoreid
1
Using where
2つ目はKEYで、サブクエリではジャンプレコードしかスキャンされませんでした.
明らかです.この場合、2番目は1番目より効率が高いです.
本文は“神様、私たちは会わないと散らない!”のブログから出て、転載して作者と連絡してください!
推奨:MAX関数とGROUP BY文で使用されるエラーhttp://yueliangdao0608.blog.51cto.com/397025/81278