获取与MIN / MAX SUM值相关联的用户

时间:2016-02-03 22:02:51

标签: php mysql

我有这个问题:

SELECT 
    MIN(totalDuration) AS lowestTotalDuration,
    MAX(totalDuration) AS highestTotalDuration
FROM 
    (SELECT 
        SUM(totalDuration) AS totalDuration
    FROM 
        activity
    WHERE 
        active = :active
    GROUP BY 
        userID
    ) activity

但是我也希望获得与每个MIN / MAX结果相关联的userID,以便知道哪个用户拥有最少/最多。

我尝试将userID添加到查询中,但它只生成MAX值的userID。

数据库结构是:

userID    totalDuration    active
---------------------------------
1         0.0100           1
1         0.3000           1
2         0.2000           1
2         0.1000           1
3         0.0020           1

查询应该产生:

([lowestTotalDuration] => 0.0020
 [lowestUserID] => 3
 [highestTotalDuration] => 0.3100
 [highestUserID] => 1)

感谢。

2 个答案:

答案 0 :(得分:1)

如果查询运行时间不长,请使用union all

(SELECT userId, SUM(totalDuration) AS totalDuration
 FROM activity
 WHERE active = :active
 GROUP BY userID  
 ORDER BY totalDuration ASC
 LIMIT 1
) UNION ALL
(SELECT userId, SUM(totalDuration) AS totalDuration
 FROM activity
 WHERE active = :active
 GROUP BY userID  
 ORDER BY totalDuration DESC
 LIMIT 1
);

如果您有更大的数据,那么您可以为此目的使用变量:

SELECT userId, totalDuration
FROM (SELECT a.*,
             (@min := if(@min = -1 or @min < totalDuration, totalDuration, @min) as minval,
             (@max := if(@max = -1 or @max > totalDuration, totalDuration, @max) as maxval       
      FROM (SELECT userId, SUM(totalDuration) AS totalDuration
            FROM activity
            WHERE active = :active
            GROUP BY userID
           ) a CROSS JOIN
           (SELECT @min := -1, @max := -1) params
      ) a
WHERE totalDuration IN (minval, maxval);

答案 1 :(得分:0)

我假设您使用mysql,因为您使用mysql标记它。您可以尝试使用存储过程(或每次执行此SQL),如下所示:

CREATE TEMPORARY TABLE IF NOT EXISTS activity_temp AS (SELECT
                                              SUM(totalDuration) AS totalDuration
                                            FROM
                                              activity
                                            WHERE
                                              active = :active
                                            GROUP BY
                                              userID
);
SELECT
  (@minvalue:=MIN(totalDuration)) AS lowestTotalDuration,
  (@maxvalue:=MAX(totalDuration)) AS highestTotalDuration
FROM activity_temp;
SELECT (@minvalueId:=userID) FROM activity_temp WHERE totalDuration = @minvalue LIMIT 1;
SELECT (@maxvalueId:=userID) FROM activity_temp WHERE totalDuration = @maxvalue LIMIT 1;
SELECT @minvalueId, @minvalue, @maxvalueId, @maxvalue;