tags:

views:

66

answers:

4

Hi,

I have written a code where i am frequently tripping to database which is kinda awkward, i am using the code to count the number of approves, pending, and spam in comments table.

here is my code.

 $query_approved = "SELECT COUNT(*) as approved FROM comments WHERE approve = '1'";
 $result_approved = mysql_query($query_approved);
 $row_approved = mysql_fetch_array($result_approved);
 $query_unapproved = "SELECT COUNT(*) as unapproved FROM comments WHERE approve = '0'";
 $result_unapproved = mysql_query($query_unapproved);
 $row_unapproved = mysql_fetch_array($result_unapproved);
 $query_spam = "SELECT COUNT(*) as spam FROM comments WHERE spam = '1'";
 $result_spam = mysql_query($query_spam);
 $row_spam = mysql_fetch_array($result_spam);

although that code works fine but it looks ugly. is there anyway to improve that?

+2  A: 

use:

SELECT SUM(CASE WHEN c.approved = '1' THEN 1 ELSE 0 END) AS cnt_approved,
       SUM(CASE WHEN c.approved = '0' THEN 1 ELSE 0 END) AS cnt_unapproved,
       SUM(CASE WHEN c.spam = '1' THEN 1 ELSE 0 END) AS cnt_spam
  FROM COMMENTS c
OMG Ponies
what is the c in the end?
Ibrahim Azhar Armar
OMG Ponies
i tested all the queries suggested by people, and the most feasible solution i found was yours, it worked without any glitches. and yes alias is something i found to play around with. thank you for that answer. i am going with your code :)
Ibrahim Azhar Armar
i would appreciate if you explain me the condition THEN 1 ELSE 0 END i am kinda confused about it :)
Ibrahim Azhar Armar
i got it, it will look into the table where the value is 1 and it will sum up and count the value and will print the total 1's found.. is it not?
Ibrahim Azhar Armar
@Ibrahim Azhar Armar: `CASE` is the ANSI SQL eqivalent to an IF/ELSE (better yet, SWITCH) statement. The logic is looking at the evaluation, and returning a value of one if the record matches the criteria (zero otherwise). Then it SUMs those values, given an equivalent to using COUNT but more flexible.
OMG Ponies
thank you that perfectly make sense to me now...:)
Ibrahim Azhar Armar
+1  A: 

You could combine:

SELECT SUM(approve) as approved, SUM(spam) AS spam, 
    SUM(approved) - COUNT(*) as unapproved 
FROM comments

Looking at the first three answers (including this), I lean toward Kelsey's approach as the most mantainable.

egrunin
How do you come to the conclusion that three separate passes over the same table is more maintainable?
OMG Ponies
Because I understood what it was doing as soon as I read it, while yours and mine require thinking; mine because of the SUM() trick, yours because of the SUM() and CASE(). Yours is the most **efficient**, of course.
egrunin
A: 

You can optimize first two call in one call

$query_approved = "SELECT COUNT(*) as totalCount , approve as status FROM comments group by approve";
 $result_approved = mysql_query($query_approved);
 $rows = mysql_fetch_array($result_approved);
foreach($rows as $row)
{
     if($row['status'] == '1')
     {
           $row_approved = $row['totalCount'];
     }
     elseif ($row['status'] == '0')
     {
           $row_unapproved = $row['totalCount'];
     }
}

 $query_spam = "SELECT COUNT(*) as spam FROM comments WHERE spam = '1'";
 $result_spam = mysql_query($query_spam);
 $row_spam = mysql_fetch_array($result_spam);
Maulik Vora
A: 

A more efficient single query might be:

$SQL = "SELECT approve, spam, count(*) as cnt FROM comments GROUP BY approve, spam";
$result_approved = mysql_query($SQL );
$rows= mysql_fetch_row($result_approved);

Then, you can foreach the $rows ...

foreach ( $rows as $row ) {
   $row[0] is the approved code (1 or 0)
   $row[1] is the spam flag (1 or 0)
   $row[2] is the count for this criteria
}

You'll end up with 4 rows, one each for approved that is spam, not spam, not approved that is spam and is not spam.

Coach John