Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A SQL query to select until SUM(users_count) reaches 1000

I need a sql query to select rows from my messages queue, until SUM(users_count) reaches at most 1000. BUT there is no problem if there be only one row returned and that row's users_count is greater than 1000.

I need something like: (i added my own keywords)

SELECT * FROM `messages_queue` UNTIL SUM(users_count) < 1000 AT LEAST 1 ROW

This is my table structure:

messages_queue
- msg_id
- msg_body
- users_count (number of message recieptors)
- time (insert time)

like image 737
Aram Alipoor Avatar asked Aug 17 '11 18:08

Aram Alipoor


People also ask

Can I use sum and Max in same query?

SUM() and MAX() at the same time Notice that all aggregate functions except COUNT(*) ignore the NULL Rating for the ID=5 row. COUNT(*) counts rows, whereas COUNT(col) counts non-null values. So to answer your question, just go ahead and use SUM() and MAX() in the same query.

How do you sum amounts in SQL?

If you need to add a group of numbers in your table you can use the SUM function in SQL. This is the basic syntax: SELECT SUM(column_name) FROM table_name; The SELECT statement in SQL tells the computer to get data from the table.

How do you order something from lowest to highest in SQL?

The SQL ORDER BY Keyword The ORDER BY keyword is used to sort the result-set in ascending or descending order. The ORDER BY keyword sorts the records in ascending order by default. To sort the records in descending order, use the DESC keyword.

What is Max () +1 SQL?

MAX(x) - 1 simply means the max value of x in the table minus one. You can always use parenthesis and aliases ( as some_cool_name ) to make thing clearer, or to change names in the result. But the first syntax is perfectly valid.


1 Answers

This solution will perform a cumulative sum, stopping when the sum exceeds 1000:

SELECT NULL AS users_count, NULL AS total
  FROM dual
 WHERE (@total := 0)
 UNION
SELECT users_count, @total := @total + users_count AS total
  FROM messages_queue
 WHERE @total < 1000;

That means that if you have two values of, say, 800, the sum total will be 1600. The first SELECT is just to initialise the @total variable.

If you want to prevent the sum from exceeding 1000, apart from in cases where a single row has a value of greater than 1000, then I think this works, although you'll need to subject it to some rigorous testing:

SELECT NULL AS users_count, NULL AS total, NULL AS found
  FROM dual
 WHERE (@total := 0 OR @found := 0)
 UNION
SELECT users_count, @total AS total, @found := 1 AS found
  FROM messages_queue
 WHERE (@total := @total + users_count)
   AND @total < 1000
 UNION
SELECT users_count, users_count AS total, 0 AS found
  FROM messages_queue
 WHERE IF(@found = 0, @found := 1, 0);
like image 189
Mike Avatar answered Sep 26 '22 10:09

Mike