贴建表及插入记录的SQL,及要求结果出来看看select * from tt a where not exists(select 1 fromn tt where a.Type=Type and a.Level<Level)
CREATE TABLE IF NOT EXISTS `test` ( `Id` int(11) NOT NULL, `PlayerId` int(11) NOT NULL, `Type` int(11) NOT NULL, `Level` tinyint(4) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `test`.`test` (`Id`, `PlayerId`, `Type`, `Level`) VALUES (NULL, '1', '1', '2'), (NULL, '1', '1', '13'), (NULL, '1', '2', '23'), (NULL, '1', '2', '3'), (NULL, '1', '3', '24'); EXPLAIN SELECT C.`Id` FROM ( SELECT * FROM `test` WHERE `PlayerId` = 1 ORDER BY `Level` DESC ) AS C GROUP BY C.`Type` 这样的执行效率太低了。
SELECT * FROM TEST a WHERE NOT EXISTS(SELECT 1 FROM TEST WHERE a.Type=TYPE AND a.Level<LEVEL)在Type、Level上建立复合索引
-- 按照type 进行分组,Level 的id( so easy) SELECT id,TYPE,MAX(LEVEL) FROM test GROUP BY TYPE;
-- 按照type 进行分组,Level 的id( so easy) SELECT id,TYPE,MAX(LEVEL) FROM test GROUP BY TYPE;-----------------------------------------------------------------额这个有问题,呵呵,错了
版主,少了个user。
2楼的数据中没有user嘛。
我Sb了结构应该是这样的。 CREATE TABLE IF NOT EXISTS `test` ( `Id` int(11) NOT NULL auto_increment, `PlayerId` int(11) NOT NULL, `Type` int(11) NOT NULL, `Star` tinyint(4) NOT NULL, `Level` tinyint(4) NOT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ; INSERT INTO `test`.`test` (`Id`, `PlayerId`, `Type`,`Star` , `Level`) VALUES (NULL, '1', '1', '2' ,'2'), (NULL, '1', '1', '1' , '13'), (NULL, '1', '2', '3' , '23'), (NULL, '1', '2', '1' , '3'), (NULL, '1', '3', '2' , '24');
要Star倒序,level倒序。Playerid = 1 Group BY TYPE,取得Id
SELECT * FROM ( SELECT * FROM `test` WHERE `PlayerId` = 1 ORDER BY `Star` DESC , `Level` DESC ) AS C GROUP BY C.`Type PlayerId Id Type Star Level 1 1 1 2 2 1 3 2 3 23 1 5 3 2 24
SELECT * FROM TEST a WHERE NOT EXISTS(SELECT 1 FROM TEST WHERE a.Type=TYPE AND a.star<star)
or SELECT * FROM TEST a WHERE NOT EXISTS(SELECT 1 FROM TEST WHERE a.Type=TYPE AND (a.star<star OR a.star=star AND a.level<LEVEL))
这个可以 ,不过Player加到那里?谢谢大神~
SELECT * FROM TEST a WHERE NOT EXISTS(SELECT 1 FROM TEST WHERE a.Type=TYPE AND (a.star<star OR a.star=star AND a.level<LEVEL)) and a.Playerid=1
INSERT INTO `test` (`Id`, `PlayerId`, `Type`, `Star`, `Level`) VALUES (2, 1, 1, 1, 13),(8, 1, 1, 1, 50),(1, 1, 1, 2, 2),(4, 1, 2, 1, 3),(3, 1, 2, 3, 23),(5, 1, 3, 2, 24),(6, 2, 1, 1, 1),(7, 2, 5, 1, 1); SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = Type AND ( a.Star < Star OR a.Star = Star AND a.Level < Level ) ) AND a.PlayerId = 2 这样查不出来。
SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = Type AND ( a.Star < Star OR a.Star = Star AND a.Level < Level ) AND PlayerId = 2 ) AND a.PlayerId = 2 这样就好了。
这样的数据不能排除重复的数据呢 加入唯一标识的字段IDSELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = `Type` AND (a.Star < Star OR (a.Star=Star AND a.Level < `Level`) OR (a.Star = Star AND a.Level= `LEVEl` AND a.id<id) )) AND a.`PlayerId`=2
SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = `Type` AND (a.Star < Star OR (a.Star=Star AND a.Level < `Level`) OR (a.Star = Star AND a.Level= `LEVEl` AND a.id<id) )) AND a.`PlayerId`=1
SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = `Type` AND ( a.Star < Star OR ( a.Star=Star AND a.Level < `Level` ) OR( a.Star = Star AND a.Level = `LEVEl` AND a.id < id ) ) AND `PlayerId`=1 ) AND a.`PlayerId`=1 这个成功了。但是效率比SELECT * FROM ( SELECT * FROM `test` WHERE `PlayerId` = 1 ORDER BY `Star` DESC , `Level` DESC ) AS C GROUP BY C.`Type慢多了。
SELECT * FROM ( SELECT * FROM `test` WHERE `PlayerId` = 1 ORDER BY `Star` DESC , `Level` DESC ) AS C GROUP BY C.`Type 不是标准的SQL语句在Type、Star、Level、id、PlayerId上建立复合索引
create index xxx on `test` (PlayerId,C.`Type,`Star` DESC , `Level` DESC )select * from from `test` USE INDEX (xxx) where `PlayerId` = 1 GROUP BY C.`Typeselect * from `test` a where `PlayerId` = 1 and not exists (select 1 from `test` where `PlayerId` = 1 and `Type` =a.`Type` and (`Star`>a.`Star` or (`Star`=a.`Star` and `Level`>a.`Level`)))
and a.Level<Level)
`Id` int(11) NOT NULL,
`PlayerId` int(11) NOT NULL,
`Type` int(11) NOT NULL,
`Level` tinyint(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test`.`test` (`Id`, `PlayerId`, `Type`, `Level`) VALUES (NULL, '1', '1', '2'), (NULL, '1', '1', '13'), (NULL, '1', '2', '23'), (NULL, '1', '2', '3'), (NULL, '1', '3', '24');
EXPLAIN SELECT C.`Id` FROM ( SELECT * FROM `test` WHERE `PlayerId` = 1 ORDER BY `Level` DESC ) AS C GROUP BY C.`Type`
这样的执行效率太低了。
AND a.Level<LEVEL)在Type、Level上建立复合索引
SELECT id,TYPE,MAX(LEVEL) FROM test GROUP BY TYPE;
SELECT id,TYPE,MAX(LEVEL) FROM test GROUP BY TYPE;-----------------------------------------------------------------额这个有问题,呵呵,错了
CREATE TABLE IF NOT EXISTS `test` (
`Id` int(11) NOT NULL auto_increment,
`PlayerId` int(11) NOT NULL,
`Type` int(11) NOT NULL,
`Star` tinyint(4) NOT NULL,
`Level` tinyint(4) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
INSERT INTO `test`.`test` (`Id`, `PlayerId`, `Type`,`Star` , `Level`) VALUES (NULL, '1', '1', '2' ,'2'), (NULL, '1', '1', '1' , '13'), (NULL, '1', '2', '3' , '23'), (NULL, '1', '2', '1' , '3'), (NULL, '1', '3', '2' , '24');
PlayerId
Id Type Star Level
1 1 1 2 2
1 3 2 3 23
1 5 3 2 24
AND a.star<star)
SELECT * FROM TEST a WHERE NOT EXISTS(SELECT 1 FROM TEST WHERE a.Type=TYPE
AND (a.star<star
OR
a.star=star AND a.level<LEVEL))
这个可以 ,不过Player加到那里?谢谢大神~
AND (a.star<star
OR
a.star=star AND a.level<LEVEL))
and a.Playerid=1
(2, 1, 1, 1, 13),(8, 1, 1, 1, 50),(1, 1, 1, 2, 2),(4, 1, 2, 1, 3),(3, 1, 2, 3, 23),(5, 1, 3, 2, 24),(6, 2, 1, 1, 1),(7, 2, 5, 1, 1);
SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = Type AND ( a.Star < Star OR a.Star = Star AND a.Level < Level ) ) AND a.PlayerId = 2
这样查不出来。
SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = Type AND ( a.Star < Star OR a.Star = Star AND a.Level < Level ) AND PlayerId = 2 ) AND a.PlayerId = 2
这样就好了。
(2, 1, 1, 1, 13),(8, 1, 1, 1, 50),(1, 1, 1, 2, 2),(9, 1, 1, 2, 2),(4, 1, 2, 1, 3),(3, 1, 2, 3, 23),(5, 1, 3, 2, 24),(6, 2, 1, 1, 1),(7, 2, 5, 1, 1);
这样的数据不能排除重复的数据呢。PlayerId = 1
加入唯一标识的字段IDSELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = `Type`
AND (a.Star < Star OR (a.Star=Star AND a.Level < `Level`)
OR
(a.Star = Star AND a.Level= `LEVEl` AND a.id<id)
))
AND a.`PlayerId`=2
AND (a.Star < Star OR (a.Star=Star AND a.Level < `Level`)
OR
(a.Star = Star AND a.Level= `LEVEl` AND a.id<id)
))
AND a.`PlayerId`=1
SELECT * FROM test a WHERE NOT EXISTS(SELECT 1 FROM test WHERE a.Type = `Type` AND ( a.Star < Star OR ( a.Star=Star AND a.Level < `Level` ) OR( a.Star = Star AND a.Level = `LEVEl` AND a.id < id ) ) AND `PlayerId`=1 ) AND a.`PlayerId`=1
这个成功了。但是效率比SELECT * FROM ( SELECT * FROM `test` WHERE `PlayerId` = 1 ORDER BY `Star` DESC , `Level` DESC ) AS C GROUP BY C.`Type慢多了。
不是标准的SQL语句在Type、Star、Level、id、PlayerId上建立复合索引
from from `test` USE INDEX (xxx)
where `PlayerId` = 1
GROUP BY C.`Typeselect *
from `test` a
where `PlayerId` = 1
and not exists (select 1 from `test` where `PlayerId` = 1 and `Type` =a.`Type` and (`Star`>a.`Star` or (`Star`=a.`Star` and `Level`>a.`Level`)))