views:

63

answers:

3

I have a classifieds website, and it is using MySQL as a database.

My goal is to show the number of private, company and total ads in the db with the search-term entered in a text-input inside the form!

The Problem: There are two types of ads: Private, and Company. The user may specify which to display, or both, so thats three options.

On the website, after displaying the search results, I want to show the user THREE tabs: All ads, Private ads, Company ads.

I have a field in every record in MySQL which contains the value of either Private or Company.

I know of a way to display the number of private ads, company ads and TOTAL ads but it requires multiple queries.

For example, if the user CHECKS the PRIVATE ONLY check-box then only private ads are searched, but I won't know how many company ads there are until I make a new query, where I search also for company ads. Then add them, and I have also the total nr of ads.

Just wonder if you know of a good way, to maybe get rid of the extra query?

Thanks

+2  A: 
SELECT field , COUNT( id ) 
FROM db
GROUP BY field;
Brock Batsell
+1, this is why we have databases: data transformation. Sure, querying makes more sense than searching flatfiles, to be sure, but they're more than just a storage engine; any chance you get to make the database do the job it was built for, do it!
Dereleased
A: 

Query all of the data at once and pass it off to PHP. Once you have it in PHP set up three separate loops.. Eg:

foreach($data AS $row)
{
    if($row['type'] == 'company')
    {
        // LOOP THROUGH COMPANY DATA
    }
}

foreach($data AS $row)
{
    if($row['type'] == 'private')
    {
        // LOOP THROUGH PRIVATE DATA
    }
}

This way you only pull your data set once, but you can surgically show the data you want from the set in each tab separately.

If you are just wanting counts use a GROUP BY clause when you select your counts.

angryCodeMonkey
This is pretty horrible from a large-scale data perspective. When you have 100,000+ rows of data, and a user is not looking at all ads, you will be returning massive volumes of data that you know will not be needed. Let the DB do its job instead, returns counts and only the data you know you need.
macabail
@macabail you are correct, I beleive I actually misread the question and didn't realize we were only talking about counts. I anticipated that he wanted to show counts on tabs as well as have the body listed (like in a table) inside of the tabs. If that were the case then a single query would be the way to go. I don't know WHERE I got the impression he was showing data on tabs.. Must have been sleepy.. =) Good catch on my thinking though!
angryCodeMonkey
+3  A: 

You could use a ROLLUP:

SELECT
    IFNULL( field , 'All ads' ) AS 'Type',
    COUNT( * )
FROM
    `table`
GROUP BY
    field
WITH ROLLUP

So with four Company and one Private ad you would see:

Type       COUNT( * )
Company    4
Private    1
All ads    5
martin clayton
+1 I have never seen this clause before and just checked the documentation. I can imagine, that this is extremely powerful! Thanks!
Cassy
I, too, didn't know about ROLLUP. That's pretty neat. I do wonder, though, if IFNULLing every single row would result in slower performance than simply adding up the two numbers in PHP afterward.
Brock Batsell
@Brock - I doubt the IFNULL would have much of an impact. By the time it's applied the dataset will be down to the grouped rows only. Perhaps more likely is that the WITH ROLLUP itself might be expensive. One advantage though is that the calling code is simplified.
martin clayton