问题
I have the following query which returns 250 records:
SELECT DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')
LIMIT 240,10;
-- Returns 198 records
SELECT DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')
-- Returns 250 records. Why?
SELECT DISTINCT COUNT(*) FROM Persons AS p
INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')
When I execute the above, I see no records even though there are 250 total. It only starts to return records when I change the LIMIT
to LIMIT 197,10
, then I see 1 of the records.
Why is this happening?
回答1:
You have distinct in the wrong place for the count. Your counting all rows (250) and selecting the distinct row values. There is only 1 row which is 250.
What you meant was select count(distinct p.*) Which will then return 198
回答2:
By default the order is ASC
try to reverse the order and get only 10 records like that
Order by RAND () LIMIT 10
Without ORDER BY, there is no default sort order. so if you are not specified the order then its random then you can simply limit 10 records without setting the position 240.
EDIT:
SELECT COUNT(*) as counts FROM Persons AS p
INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')
GROUP BY c.Id ORDER BY c.Id LIMIT 240,10
回答3:
I've re-read the question, and it's not clear to me which queries are returning what.
What we'd expect:
first query: no rows returned (only 198 distinct rows, there aren't 240 rows to skip)
second query: 198 rows returned, sounds reasonable
third query: returns 1 row with value of 250, which again is reasonable.
If that's the behavior you are seeing, then this is all to be expected.
The DISTINCT operator eliminates duplicate rows, which explains the difference between 198 and 250. And since the LIMIT is applied as the last step (or nearly the last step) in the execution plan, that explains why no rows are returned by the first query.
To get the count of the 198 rows returned by the second query, one easy way to get that would be to wrap that second query (which returns the 198 rows) in another query that gets a COUNT from that.
SELECT COUNT(1) AS mycount
FROM (
SELECT DISTINCT p.*
FROM Persons p
JOIN Colors c
ON c.ColorId = p.FavoriteColorId
AND c.ColorName IN ('RED','BLUE','YELLOW')
WHERE p.Name = 'John Doe'
) q
If you want a count of rows from the Persons
table, without eliminating any duplicates from the Persons table, then one way to get that would be:
SELECT COUNT(1) AS mycount
FROM Persons p
WHERE p.Name = 'John Doe'
AND EXISTS ( SELECT 1
FROM Colors c
WHERE c.ColorName IN ('RED','BLUE','YELLOW')
AND c.ColorId = p.FavoriteColorId
)
If you have a single column that is UNIQUE and NOT NULL in the Persons table, for example, an id INT PRIMARY KEY
, you could do this:
SELECT COUNT(DISTINCT p.id) AS mycount
FROM Persons p
JOIN Colors c
ON c.ColorName IN ('RED','BLUE','YELLOW')
AND c.ColorId = p.FavoriteColorId
WHERE p.Name = 'John Doe'
ORIGINAL ANSWER
That first query should be returning no more than 10 rows.
You report that the second query returns 198 rows. I don't see how that first query (identical to this except for the addition the LIMIT clause) should be returning any rows, if that's true.
The third query should be returning a single row.
There's no good explanation for the results you are seeing.
Q Can you replicate this behavior in the msyql command line client, just to rule out behavior in the client application you are using.
Q What version of MySQL are you running? (This could be a bug in your version of MySQL.)
Q What engine are these tables using (MyISAM, InnoDB)?
Q Have you verified your tables are consistent with
CHECK TABLE tablename EXTENDED
?Q And you've verified that some other process isn't inserting, updating and/or deleting rows while your queries are running?
Your first query is a bit odd, in that it specifies a LIMIT
clause, but there is no GROUP BY
or ORDER BY
clause or anything else that prescribes what order the rows should be returned in.
The third query is a bit odd in that the DISTINCT
keyword is not needed. Absent a GROUP BY
clause, we expect SELECT COUNT(*)
to return a single row.
Part of me questions whether the reporting of the observed behavior is accurate. Is that third query really returning 250 rows, or is it returning a single row with a value of 250 for the count? (Those are two very different things.)
We'd normally expect a SELECT COUNT(*)
to return a value larger than the the number of rows returned by SELECT DISTINCT p.*
in cases where the DISTINCT
operator is eliminating duplicate rows.
来源:https://stackoverflow.com/questions/18025315/no-mysql-records-return-when-past-a-certain-limit