At 7:40 PM -0400 9/18/01, Raymond Prisament wrote:
>In the course of using MySQL the following issue has come up a few times; I
>am unaware of the solution for it, but I am sure one exists, since it seems
>fairly elementary. It has to do with the COUNT(*) and GROUP BY functions.
>
>Let's say I have clients, and clients buy items.
>
>table clients:
>---------------------------------
>ClientID | ClientName
>---------------------------------
>1 | John
>2 | Mary
>--------------------------------
>
>table items:
>---------------------------------------------------
>ClientIDWhoBoughtIt | ItemName
>---------------------------------------------------
>1 | Dishwasher
>1 | Light Bulb
>1 | Grill
>---------------------------------------------------
>
>Notice that John has bought three things, and Mary did not buy anything.
>
>Now, I want a report on how many items each client has bought. The way you
>are supposed to do this is:
>
>SELECT ClientName, COUNT(*) AS itemcount FROM clients, items WHERE
>clients.ClientID = items.ClientIDWhoBoughtIt GROUP BY clients.ClientID
Which will return results only for rows where a match can be found in
both tables.
>
>This will return:
>
>--------------------------------------------------
>ClientName | itemcount
>--------------------------------------------------
>John | 3
>--------------------------------------------------
>
>Which is nice, but is not what I want, because I don't get any information
>about Mary. What I want, obviously, is:
>
>--------------------------------------------------
>ClientName | itemcount
>--------------------------------------------------
>John | 3
>Mary | 0
>--------------------------------------------------
Which means you want a result even for clients that are missing
in the item table. Aha, missing rows. That means a LEFT JOIN.
SELECT ClientName, COUNT(items.ClientIDWhoBoughtIt) AS itemcount
FROM clients LEFT JOIN items ON clients.ClientID = items.ClientIDWhoBoughtIt
GROUP BY clients.ClientID
So the problem isn't really your GROUP BY. The trick is to realize
that you want to join to produce a row for every clients row, even
when there's no match in the other table. LEFT JOIN does this. It
produces a row with the clients columns filled in and the items columns
set to NULL.
But you also need to change COUNT(*) to COUNT(items.ClientIDWhoBoughtIt)
because COUNT(*) counts all rows where as COUNT(col_name) counts only
non-NULL values.
>
>Is there any way to get that result? I would think there must be. Such
>functionality is vital if, say, you want to build a report with an
>alphabetical list of everyone who's signed up for your web site, and the
>number of things they've bought. It doesn't make sense to not list their
>names simply because they signed up and didn't buy anything yet - that may
>be valid information.
>
>I would greatly appreciate anyone's input into this.
>
>Sincerely,
>
>Ray Prisament
>
>
>
>---------------------------------------------------------------------
>Before posting, please check:
> http://www.mysql.com/manual.php (the manual)
> http://lists.mysql.com/ (the list archive)
>
>To request this thread, e-mail <[EMAIL PROTECTED]>
>To unsubscribe, e-mail <[EMAIL PROTECTED]>
>Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
--
Paul DuBois, [EMAIL PROTECTED]
---------------------------------------------------------------------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)
To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php