group by month and year, count from another table

喜欢而已 提交于 2019-12-20 06:28:09

问题


im trying to get my query to group rows by month and year from the assignments table, and count the number of rows that has a certain value from the leads table. they are linked together as the assignments table has an id_lead field, which is the id of the row in the leads table.

d_new would be a count of the assignments for leads for the month whose website is newsite.com d_subprime would be a count of the assignments for leads for the month whose website is not newsite.com

here are the tables being used:

`leads`
id (int)
website (varchar)

`assignments`
id_lead (int)
date_assigned (int)

heres my query which is not working:

SELECT 
  MONTHNAME(FROM_UNIXTIME(a.date_assigned)) as d_month, 
  YEAR(FROM_UNIXTIME(a.date_assigned)) as d_year, 
  (select COUNT(*) from leads where website='newsite.com' ) as d_new,
  (select COUNT(*) from leads where website!='newsite.com') as d_subprime
FROM assignments as a
left join leads as l on (l.id = a.id_lead)
where id_dealership='$id_dealership2'
GROUP BY 
  d_month, 
  d_year
ORDER BY
    d_year asc,
    MONTH(FROM_UNIXTIME(a.date_assigned)) asc

$id_dealership is a variable containing a id of the dealership im trying to view the count for.

any help would be greatly appreciated.


回答1:


You can sort of truncate your timestamps to months and use the obtained values for grouping, then derive the necessary date parts from them:

SELECT
  YEAR(d_yearmonth) AS d_year,
  MONTHNAME(d_yearmonth) AS d_month,
  …
FROM (
  SELECT
    LAST_DAY(FROM_UNIXTIME(a.date_assigned)) as d_yearmonth,
    …
  FROM assignments AS a
    LEFT JOIN leads AS l ON (l.id = a.id_lead)
  WHERE id_dealership = '$id_dealership2'
  GROUP BY
    d_yearmonth
) AS s
ORDER BY
  d_year            ASC,
  MONTH(d_yearmonth) ASC

Well, LAST_DAY() doesn't really truncate a timestamp, but it does turn all the values belonging to the same month into the same value, which is basically what we need.

And I guess the counts should be related to the rows you are actually selecting, which is not what your subqueries are. Something like this might do:

…
COUNT(d.website = 'newsite.com' OR NULL) AS d_new,
/* or: COUNT(d.website) - COUNT(NULLIF(d.website, 'newsite.com')) AS d_new */
COUNT(NULLIF(d.website, 'newsite.com'))  AS d_subprime
…

Here's the entire query with all the modifications mentioned:

SELECT
  YEAR(d_yearmonth) AS d_year,
  MONTHNAME(d_yearmonth) AS d_month,
  d_new,
  d_subprime
FROM (
  SELECT
    LAST_DAY(FROM_UNIXTIME(a.date_assigned)) as d_yearmonth,
    COUNT(d.website = 'newsite.com' OR NULL) AS d_new,
    COUNT(NULLIF(d.website, 'newsite.com'))  AS d_subprime
  FROM assignments AS a
    LEFT JOIN leads AS l ON (l.id = a.id_lead)
  WHERE id_dealership = '$id_dealership2'
  GROUP BY
    d_yearmonth
) AS s
ORDER BY
  d_year            ASC,
  MONTH(d_yearmonth) ASC



回答2:


This should do the trick:

SELECT
YEAR(FROM_UNIXTIME(a.date_assigned)) as d_year, 
MONTHNAME(FROM_UNIXTIME(a.date_assigned)) as d_month,
l.website,
COUNT(*)
FROM
assignments AS a
INNER JOIN leads AS l on (l.id = a.id_lead) /*are you sure, that you need a LEFT JOIN?*/
WHERE id_dealership='$id_dealership2'
GROUP BY
d_year, d_month, website
/*an ORDER BY is not necessary, MySQL does that automatically when grouping*/

If you really need a LEFT JOIN, be aware that COUNT() ignores NULL values. If you want to count those as well (which I can't imagine to make sense) write it like this:

SELECT
YEAR(FROM_UNIXTIME(a.date_assigned)) as d_year, 
MONTHNAME(FROM_UNIXTIME(a.date_assigned)) as d_month,
l.website,
COUNT(COALESCE(l.id, 1))
FROM
assignments AS a
LEFT JOIN leads AS l on (l.id = a.id_lead)
WHERE id_dealership='$id_dealership2'
GROUP BY
d_year, d_month, website



回答3:


Start with

SELECT 
  MONTHNAME(FROM_UNIXTIME(a.date_assigned)) as d_month, 
  YEAR(FROM_UNIXTIME(a.date_assigned)) as d_year, 
  SUM(IF(l.website='newsite.com',1,0) AS d_new,
  SUM(IF(l.website IS NOT NULL AND l.website!='newsite.com',1,0) AS d_subprime
FROM assignments AS a
LEFT JOIN leads AS l ON l.id = a.id_lead
WHERE id_dealership='$id_dealership2'
GROUP BY 
  d_month, 
  d_year
ORDER BY
    d_year asc,
    MONTH(FROM_UNIXTIME(a.date_assigned)) asc

and work from here: The field id_dealership is neither in leads nor in assignments, so you need more work.

If you edit your question to account for id_dealership we might be able to help you further.



来源:https://stackoverflow.com/questions/9699533/group-by-month-and-year-count-from-another-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!