0

这是问题所在。我已经浏览了这些线程一段时间,但还没有找到确切的解决方案。

我有两个表,就像大多数问题一样,这与加入这两个表有关。一个基本上是一个表,其中包含 20,000 多条记录的跑步者列表,第二个表是那些具有 35000 多条记录的跑步者的结果列表。第二个表实际上是一个视图,其中包含所有结果信息以及视图生成的年龄等级和评级。我现在需要的是结合每个跑步者的前三个评分。我首先尝试了这个。

SELECT
  r.id, 
  r.FirstName,
  r.MiddleName,
  r.LastName,
  r.Age,
  r.Gender,
  r.City,
  r.State,
  ROUND((SELECT SUM(re.Rating) rating FROM vwResults re WHERE re.runnerid = r.id ORDER BY re.Rating DESC LIMIT 3)/3,2) Rating
FROM Runners r 

不幸的是,失败了我想要做的是将结果表中的前三个评级相加,然后将其设为 3 以获得平均值。这将是该用户的平均评分。我已经尝试了上面代码的几种不同变体,我确实得到了一个部分工作,但加载 30 条记录需要 8 秒,并且数据不正确。有没有办法做到这一点,以便我可以创建一个内置评级的新 Runner 视图?如果可能的话,我宁愿不使用程序。

Runners Table Structure
id int(11)
FirstName varchar(50)
MiddleName varchar(50)
LastName varchar(50)
Age int(3)
Gender varchar(2)
City varchar(50)
State varchar(2)
userid int(11)

vwResults View Structure
DistanceID int(4)
distance varchar(100)
RaceID int(11)
name varchar(100)
FirstName varchar(50)
LastName varchar(50)
place int(100)
Gender varchar(2)
age int(11)
finistime varchar(100)
pace time
agegrade varbinary(19)
ResultID int(11)
RunnerID int(11)
typeid int(11)
ftimesec bigint(10)
Rating decimal(18,2)

我唯一需要从 vwResults 获得的前三个评级和 / 3 以获得新的平均评级和 Runners 表中的所有信息。

我正在尝试创建一个可以获取评分的函数,但我对 mysql 函数一无所知,有人可以告诉我我在这里做错了什么

      CREATE FUNCTION GetRating(
      Runnerid int( 11) 
      )
      RETURNS decimal( 18, 2) 
      READS SQL DATA
      BEGIN
      DECLARE Rat decimal(18,2);
      SELECT  ROUND(SUM(Rating)/3,2) INTO Rat  FROM vwResults WHERE runnerid = Runnerid GROUP BY runnerid
     ORDER BY Rating DESC LIMIT 3;
     RETURN(Rat);
     END

我正在尝试使下面的代码正常工作,但是它似乎存在问题,不断出现以下错误。

1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 3 行的 '' 附近使用正确的语法

        CREATE PROCEDURE usb_GetRatings() 
        BEGIN 
        SET @rank = NULL; 
        SET @prevrunnerid = NULL;  
        DROP TABLE IF EXISTS ttRunners;
        SELECT r.id, r.FirstName,r.MiddleName, 
        r.LastName,r.Age,r.Gender,r.City,r.State,  
        ROUND(top3rating.Rating, 2) as Rating  INTO ttRunners
        FROM Runners as r 
        JOIN (SELECT runnerid, AVG(Rating) as Rating 
          FROM (SELECT if(@prevrunnerid = runnerid, 
                      @rank := @rank + 1, 
                      @rank := 1) as rank, 
                   @prevrunnerid := runnerid 
                       as runnerid, 
                   Rating 
            FROM vwResults 
            ORDER BY runnerid, Rating) as sq 
         WHERE rank <= 3 
         GROUP BY runnerid) as top3rating 
        on (r.id = top3rating.runnerid); 
      END
4

1 回答 1

0

这个怎么样?把它放在一个程序中。

delimiter //

CREATE PROCEDURE get_top3_rating_avg() AS BEGIN
    SET @rank = NULL;
    SET @prevrunnerid = NULL;
    SELECT r.id, r.FirstName,r.MiddleName,
           r.LastName,r.Age,r.Gender,r.City,r.State, 
           ROUND(top3rating.Rating, 2) as Rating 
    FROM Runners as r
    JOIN (SELECT runnerid, AVG(Rating) as Rating
          FROM (SELECT if(@prevrunnerid = runnerid,
                          @rank := @rank + 1,
                          @rank := 1) as rank,
                       @prevrunnerid := runnerid
                           as runnerid,
                       Rating
                FROM vwResults
                ORDER BY runnerid, Rating) as sq
          WHERE rank <= 3
          GROUP BY runnerid) as top3rating
        on (r.id = top3rating.runnerid);
END //

delimiter ;
于 2012-07-27T03:04:09.533 回答