SQL - количество записей с объединенной суммой - PullRequest
1 голос
/ 16 августа 2011

У меня есть таблица User, подобная этой:

|  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 ]

6 голосов
/ 16 августа 2011

ГДЕ работает только для столбцов или выражений, если вы хотите фильтровать с помощью агрегатной функции (например, SUM), вы должны использовать HAVING.Например:

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

Этот запрос не имеет смысла без действительного GROUP BY, но вы понимаете: используйте HAVING для фильтрации с помощью агрегатной функции.Технически вы должны сгруппировать по идентификатору пользователя, затем выполнить подсчет и суммировать его.

2 голосов
/ 16 августа 2011

Предполагая, что у вас есть следующая таблица пожертвований (насколько я думаю, ваш столбец идентификатора указывает на пользователя, я не был бы уверен):

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

Следующий запрос даст вам количество пользователей с их общим пожертвованием <100</p>

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

Обновление на основе дополнительной информации.Я не верю, что вы можете получить то, что вы хотите, с помощью одного оператора SQL, что вам нужно сделать, это создать курсор, который зацикливается вокруг записей, которые вы хотите (в подходящем порядке), вставляя идентификатор во временную таблицу и поддерживая общее значениепожертвований.Когда сумма превысит ваш предел, вырвитесь из цикла курсора и верните результаты.Что-то вроде этого:

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;
0 голосов
/ 16 августа 2011
SELECT id, sum(donation) AS totalDonation 
FROM TableName
GROUP BY id
HAVING totalDonation < 100
...