SQL - 计算具有组合总和的记录数

时间:2011-08-16 03:41:22

标签: mysql sql aggregate-functions

我有一个与此类似的用户表:

|  ID  |  DONATION  |   RANK   |
|  4   |        10  |     12   |
|  9   |        20  |      8   |
|  2   |        40  |      5   |
|  3   |        80  |      2   |

我想构建一个查询,其中我检索捐赠总和小于100的用户数,按排名排序......类似(显然不正确):

select count(*) where sum(donation) < 100 order by rank

如果可能的话,无法弄清楚如何做到这一点。甚至不确定我是否正确地采取这种方式。任何想法或指针?

3 个答案:

答案 0 :(得分:6)

WHERE仅适用于列或表达式,如果要使用聚合函数(如SUM)进行过滤,则必须使用HAVING。例如:

  SELECT COUNT(*)
    FROM your_table
  HAVING SUM(donation) < 100 

如果没有有效的GROUP BY,这个查询就没有意义,但是你明白了这一点:使用HAVING过滤聚合函数。从技术上讲,您应该按用户ID进行分组,然后进行计数,并对计数求和。

答案 1 :(得分:2)

假设您有以下捐赠表(我认为您的ID列指向用户,我无法确定):

| ID | UserId | Donation |
| 1  | 1      | 60       |
| 2  | 1      | 35       |
| 3  | 2      | 70       |
| 4  | 2      | 40       |
| 5  | 3      | 90       |


以下查询将为您提供捐赠总额<&lt;的用户数。 100

SELECT COUNT(1)
FROM (
    SELECT  UserId
    FROM    Donations 
    GROUP BY UserId
    HAVING SUM(Donation) < 100
) AS t

根据额外信息进行更新。
我不相信你可以从单个SQL语句中得到你想要的东西,你需要做的是创建一个游标,循环你想要的记录(以适当的顺序)将id插入临时表,并维持一个总数捐款当总数高于您的限制时,请退出游标循环并返回结果。这样的事情:

CREATE PROCEDURE GetTopDontations( limit DECIMAL(...) )
BEGIN
    CREATE TEMPORARY TABLE t1 (
        id INT
    );

    DECLARE total, Donation DECIMAL(...);
    DECLARE Id INT;
    DECLARE curDonations CURSOR FOR SELECT ID, Dontaion FROM Donations ORDER BY <something relevant>;

    SET total = 0.0;
    OPEN curDonations;
    read_loop: LOOP
        FETCH curDonations INTO Id, Donation;
        INSERT INTO t1( id ) VALUES ( Id );
        SET total = total + Donation;
        IF( total > limit ) THEN
            LEAVE read_loop;
        END IF;
    END LOOP:
    CLOSE curDonations;

    SELECT d.*
    FROM    Donations d
        INNER JOIN t1
            ON d.Id = t1.Id;
END;

答案 2 :(得分:0)

SELECT id, sum(donation) AS totalDonation 
FROM TableName
GROUP BY id
HAVING totalDonation < 100