I'm trying to get a count of records matching certain criteria within a subset of the total records. I tried (and assumed this would work)
SELECT count(*)
FROM records
WHERE status = 'ADP'
LIMIT 0,10
and I assumed this would tell me how many records of status ADP were in that set of 10 records. It doesn't - it returns, in this case 30, which is the total number of ADP records in the table.
How do I just count up the records matching my criteria including the limit?
SELECT count(*)
FROM ( SELECT records
FROM table
WHERE status = 'ADP'
LIMIT 0,10
)
select count(*) from (select * from records where status='ADP' limit 0,10) as t;
Related
I have 10,000 users on registrations table and want to limit this query to 3500 users from my application. But when I investigate the logs , sometimes it counts more than 3500. I can not understand why that query returns more than limit:
select count(*)
from registrations
where (selectedtime IS NULL
AND expirationtime < NOW()
)
LIMIT 3500;
I tried manually on DB and saw sometimes more than 3500
Your query only returns 1 row, which is less than 3500.
If you want to limit the number of rows that are being counted, you need to put that in a subquery.
SELECT COUNT(*)
FROM (
SELECT 1
FROM registrations
WHERE selectedtime IS NULL AND expirationtime < NOW()
LIMIT 3500) AS x
A SELECT statement with COUNT returns the number of rows retrieved by the SELECT statement.
For performance reasons, the desired result is to limit that count.
Including a LIMIT clause in the SELECT statement will not work since it only restricts the number of rows returned, which is always one.
The solution, what I call “Limited-Count”, is done by limiting a non-count SELECT statement and wrapping it in COUNT(*).
For example:
If your count statement looks like
select count(*) from registrations where (selectedtime IS NULL AND expirationtime < NOW()) LIMIT 3500;
You can limit the results by replacing the query into:
SELECT COUNT(*) AS total
FROM (
SELECT 1
FROM registrations
WHERE selectedtime IS NULL AND expirationtime < NOW()
LIMIT 3500) AS x
If you need to know how many rows your non-count SELECT statement would have returned without the LIMIT, you could use the information function, FOUND_ROWS(). It will fetch the total rows number without running the statement again.
This does what you thought you were doing:
select count(*)
from registrations
where (selectedtime IS NULL
AND expirationtime < NOW()
)
LIMIT ROWS EXAMINED 3500;
(Available since MariaDB 5.5.21 - see https://mariadb.com/kb/en/library/limit-rows-examined/ )
I want to select the latest 100 rows and then count and group the result, instead of counting and grouping the whole table, but I can't figure out how to do it.
An example of how it might work (but this does not work):
SELECT federal_party, count(federal_party)
From (
SELECT federal_party
FROM database
ORDER BY date_updated DESC LIMIT 100
)
GROUP BY federal_party
Any idea how this would best be done?
I'm developing an application that displays rows which have columns "Time created" and "Number of Likes".
I'm trying to return the first 5 results of my query with the rows that have the most likes, and then the remaining 95 by most recent date, without duplication.
My current query only accomplishes ordering by date.
"SELECT * FROM `$category` ORDER BY time DESC LIMIT 100"
Is what I'm attempting to do possible in one query? Or will I have to perform two queries and filter out duplicate rows?
UNION automatically removes duplicate rows and LIMIT outside the parethesis applies to the whole query.
(SELECT *, like_count AS likes FROM category ORDER BY like_count DESC LIMIT 5)
UNION
(SELECT *, 0 AS likes FROM category ORDER BY time DESC)
ORDER BY likes DESC, time DESC
LIMIT 100
I have a table that has transactions with a datetime column. I'm trying to select the last 'n' records (i.e. 20 rows) but have it sorted oldest to newest.
SELECT *
FROM table
WHERE 1=1
ORDER BY table.datefield DESC
LIMIT 20;
Gives me the 20 most recent, but in the opposite order.
Is this possible in one query, or will I have to do a query to get total rows and then adjust the limit based on that so I can do the table.datefiled ASC and then limit (total rows - n), n
Building a SELECT around your original SELECT and convert this to a derived table should do it
SELECT t.*
FROM (
SELECT *
FROM table
WHERE 1=1
ORDER BY table.datefield DESC
LIMIT 20
) t
ORDER BY t.datefield
If SELECT SUM(amount) FROM transactions ORDER BY order LIMIT 0, 50 sums the amount field for the first 50 records in a table, how do a sum all records after the first 50? In other words, I'd like to do something like SELECT SUM(amount) from transactions ORDER BY order LIMIT 50, *, but that doesn't work.
SELECT SUM(amount)
FROM (
SELECT amount
FROM transactions
ORDER BY
order
LIMIT 50, 1000000000000
) q
Note that your original query:
SELECT SUM(amount)
FROM transactions
ORDER BY
order
LIMIT 0, 50
does not do what you probably think it does. It is synonymous to this:
SELECT a_sum, order
FROM (
SELECT SUM(amount) AS a_sum, order
FROM transactions
) q
ORDER BY
order
LIMIT 0, 50
The inner query (which would normally fail in any other engine but works in MySQL due to its GROUP BY extension syntax) returns only 1 records.
ORDER BY and LIMIT are then applied to that one aggregated record, not to the records of transactions.
The documentation advices to use an incredible large number as second parameter to LIMIT:
To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
There is probably a more efficient way, but you could run a count query first, to retrieve total # of rows in your table:
SELECT count(*) FROM transactions
Stuff that into a variable and use that variable as your second argument for LIMIT. You could probably do this as a nested mysql query.