tags:

views:

187

answers:

3

I'm trying to run a report on our database. We want to know the new registrations per industry per month. I've written this query:

SELECT 
  COUNT(j.jobseeker_id) as new_registrations, 
  i.description as industry_name,
  MONTHNAME(j.created_at)
FROM
  tb_jobseeker as j, tb_industry as i
WHERE 
  YEAR(j.created_at) = 2009 
AND 
  i.industry_id = j.industry_id 
GROUP BY 
  i.description, MONTHNAME(j.created_at)
HAVING
  MONTHNAME(j.created_at) =  MONTHNAME(NOW());

When I run this query, I get an empty result set. However, if I run the following:

SELECT 
  COUNT(j.seeker_id) as new_registrations, 
  i.description as industry_name,
  MONTHNAME(j.created_at)
FROM
  tb_seeker as j, tb_industry as i
WHERE 
  YEAR(j.created_at) = 2009 
AND 
  i.industry_id = j.industry_id 
GROUP BY 
  i.description, MONTHNAME(j.created_at)
HAVING
  MONTHNAME(j.created_at) =  'June';

It returns the results I'm looking for.

Any help please? I'm stumped.

Update: the query will be run at the end of every month or start of the next for the past month. So, we're now in June, but it needs to run for May. Hope that makes sense.

+2  A: 

What does:

SELECT MONTHNAME(NOW())

Return on your server?

Andomar
June. Sorry, typo above, I'll edit.
Midiane
+1  A: 

Errr.... it's not May O_o

Your query will be much more efficient if you write it like this:

SELECT 
  COUNT(j.jobseeker_id) as new_registrations, 
  i.description as industry_name,
  MONTHNAME(j.created_at)
FROM
  tb_jobseeker as j, tb_industry as i
WHERE 
  j.created_at BETWEEN '2009-05-01' AND '2009-05-31'
AND 
  i.industry_id = j.industry_id 
GROUP BY 
  i.description, MONTH(j.created_at)

You should only use HAVING if you absolutely HAVE to.

It would be even better if you could group by i.id instead of i.description, but that depends on whether i.description is unique.

Greg
See what I did there? :p
Greg
Oh sorry Greg, I meant to say June.Thanks for the answer. Is there a way to make j.created_at automated as this query will be run every month through an admin console?
Midiane
hey greg, yours seems to be the working. is there a way to avoid the hardcoded values for j.created_at?
Midiane
You could use DATE(NOW()) but it's better to "hardcode" it (in reality you'd pass it in as a parameter in your application) - if you use NOW() then the query cache can't store it.
Greg
You're very right. Passed in the parameters and it works well. Thanks, Greg.
Midiane
A: 

This query could be better written:

SELECT 
 COUNT(j.jobseeker_id) as new_registrations, 
 i.description as industry_name,
 MONTHNAME(j.created_at)
FROM
  tb_jobseeker as j, tb_industry as i
WHERE 
  YEAR(j.created_at) = YEAR(NOW())
  AND MONTH(j.created_at) =  MONTH(NOW())
  AND i.industry_id = j.industry_id 
GROUP BY 
  i.industry_id

The "HAVING" clause is applied after grouping; you'd want to apply it if you wanted to filter based on the results of the aggregate (for instance, get all industries where > 100 people applied last month). Grouping by industry_id (which I assume is the primary key) is faster than grouping by a string (industry_name and monthname). And finally, don't need to group by month if you are only selecting single month.

However, you should be getting correct data, assuming your table has information for the actual current month.

Todd Gardner
Hi toddthanks for your contribution. I tried running that query, but it returned an empty result set. Any thoughts?
Midiane
Just edited it. Sometimes you get CAST problems between numbers (2009) and literals ('2009'). It's a long shot, but maybe the new one works?
Todd Gardner
Just tried. Doesnt. Weird... will keep trying.
Midiane