MacMac
MacMac

Reputation: 35301

Counting MySQL records with a LIMIT

As I am trying to count the number of records in a table, even when the SQL statement has a LIMIT into it, overall it works, however something weird happens, the code:

$sql = "SELECT COUNT(*) AS count FROM posts
        ORDER BY post_date DESC
        LIMIT 5";

// ... mysql_query, etc

while($row = mysql_fetch_array($result))
{
    // ... HTML elements, etc
    echo $row['post_title'];

    // ... HTML elements, etc

    echo $row['count']; // this displays the number of posts (which shows "12").
}

Although, when displaying through the while loop, it displays this:

Notice: Undefined index: post_title in /Applications/MAMP/htdocs/blog/index.php on line 55

If I remove the COUNT(*) AS count, everything will display perfectly... how come it's doing this?

Upvotes: 6

Views: 9707

Answers (9)

japetko
japetko

Reputation: 358

This works for me:

$sql = "
     SELECT COUNT( po.id ) AS count, p.post_title
     FROM posts p
     JOIN posts po
     GROUP BY p.post_title
     ORDER BY p.post_date DESC
     LIMIT 5
";

Important is to JOIN the same table, but name the table differently. Do not forget GROUP BY, must be used.

Upvotes: 0

IVIR3zaM
IVIR3zaM

Reputation: 557

I had the same problem and found this article: http://www.mysqldiary.com/limited-select-count/ best way (especially for big tables) is using it like this:

SELECT COUNT(*) AS count FROM (SELECT 1 FROM posts
    ORDER BY post_date DESC
    LIMIT 5) t

now it returns a number between 0 and 5

Upvotes: 1

Mitch Grande
Mitch Grande

Reputation: 351

By including COUNT(*) AS count you've removed the actual columns that you want to get the information from. Try using

SELECT *, COUNT(*) AS count FROM posts ORDER BY post_date DESC LIMIT 5

That query will accomplish both things you're trying to do in one query, but really, these should be broken out into 2 separate queries. What is the overall purpose for having a COUNT in the query? It should be done a different way.

Upvotes: 0

JohnB
JohnB

Reputation: 18972

What everyone is trying to say is that you should opt to use 2 separate queries instead of 1 single one.

1) get row count of table

$sql = "SELECT COUNT(*) AS count FROM posts;

2) get last 5 rows of table

$sql = "SELECT * FROM posts
        ORDER BY post_date DESC
        LIMIT 5";

Upvotes: 0

ircmaxell
ircmaxell

Reputation: 165191

Don't use COUNT(*) to count the number of rows (for a lot of reasons). Write out your full query, and add SQL_CALC_FOUND_ROWS right after SELECT:

SELECT SQL_CALC_FOUND_ROWS id, title FROM foo LIMIT 5;

Then, after that query executed (right after), run:

SELECT FOUND_ROWS();

That will return the number of rows the original SELECT would have returned if you didn't have the LIMIT on the end (accounting for all joins and where clauses).

It's not portable, but it's very efficient (and IMHO the right way of handling this type of problem).

Upvotes: 17

Mike Atlas
Mike Atlas

Reputation: 8231

You're mixing up an aggregate function COUNT() with a standard selection. You can't get an accurate post title without a GROUP BY clause in your aggregate query. The easiest thing you should do is to do this two queries - one for your count, the other for your post information. Also, there's no sense in using LIMIT on an aggregate function with no other columns in your (omitted) GROUP BY - the current query will always return one row.

Upvotes: 0

Andy
Andy

Reputation: 8908

This is happening because COUNT() is an aggregate function. You will have to do two separate queries in order to get both the count of rows in the table and separate records.

Upvotes: 1

Gintautas Miliauskas
Gintautas Miliauskas

Reputation: 7892

LIMIT does not do anything here because you're selecting a single scalar. The error is shown because you are not selecting the post title, so it is not in the $row hash.

Upvotes: 1

typo.pl
typo.pl

Reputation: 8942

You're asking the SELECT statement to return only COUNT(*) AS count. If you want more columns returned, you have to specify them in the SELECT statement.

Upvotes: 0

Related Questions