I am trying to count the number of hits per country in my database, which has the following tables:
mysql> use DB; show tables;
+--------------+
| Tables_in_DB |
+--------------+
| Hits |
| Tags |
| HitTags |
+--------------+
And here are some example columns from those tables:
mysql> select * from Hits;
+---------+----------+--------------+
| HitID | HitDate | HitText |
+---------+----------+--------------+
| 0123456 | 01/01/12 | access page1 |
| 7890123 | 01/02/12 | access page2 |
| 4567890 | 01/03/12 | access page3 |
+---------+----------+--------------+
mysql> select * from Tags;
+-----------+---------+---------+
| TagID | TagType | TagText |
+-----------+---------+---------+
| 123123213 | country | USA |
| 456456456 | country | Brazil |
| 789789789 | country | China |
| 012345678 | city | London |
+-----------+---------+---------+
mysql> select * from HitTags;
+---------+-----------+
| HitID | TagID |
+---------+-----------+
| 0123456 | 123123213 |
| 7890123 | 456456456 |
| 4567890 | 789789789 |
+---------+-----------+
I want to fetch the number of hits per country, such as in the following SQL query {and pseudo code}:
SELECT DISTINCT TagText, TagID FROM Tags
WHERE TagType = 'country';
for each $row {
SELECT COUNT(HitID) As HitCount FROM HitTags
WHERE HitTags.TagID = $row[Tags.TagID];
}
I have no issue doing this when using separate queries, but I am sure there is a way of doing this more elegantly (i.e. using a single SQL query instead of one-per-country).
Maybe using a JOIN, maybe using the ANY keyword. Or maybe using some nested SELECT statements?
Here is what I have tried:
SELECT COUNT(HitID) AS HitCount, TagText FROM HitTags
JOIN Tags ON Tags.TagID =
ANY (SELECT TagID FROM Tags WHERE TagType = 'country');
But that returns a single row with the total of all hits (from everywhere, although a country is listed along with the result).
Ideally, the result would be something like:
+---------+----------+
| TagText | HitCount |
+---------+----------+
| USA | 1234 |
| Brazil | 5678 |
| China | 9012 |
+---------+----------+
I know this must be quite common (as in "yeah, I saw this in MySQL class 101")...
I searched the web a lot, but everybody seems to be using a single table (instead of three). I'm really no good with those "one-to-many" relationships. Sorry to be such a newbie!
Any idea, hint or advice would be useful, thanks in advance!
You are just missing a GROUP BY
clause:
SELECT
COUNT(HitID) AS HitCount,
TagText
FROM HitTags
JOIN Tags ON Tags.TagID =
ANY (SELECT TagID FROM Tags WHERE TagType = 'country')
GROUP BY TagText;
Actually, this is better with a LEFT JOIN
:
SELECT
COUNT(HitID) AS HitCount,
TagText
FROM
Tags
LEFT JOIN HitTags ON Tags.TagID = HitTags.TagID
GROUP BY TagText
Try this:
SELECT *, (SELECT COUNT(HitID) FROM HitTags WHERE TagID = t.TagID ) AS hit_count
FROM Tags t WHERE TagType = 'country'
This would do the same but I think is faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With