group by month and year, count from another table

前端 未结 3 2143
北海茫月
北海茫月 2021-01-26 11:23

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

相关标签:
3条回答
  • 2021-01-26 11:43

    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
    
    0 讨论(0)
  • 2021-01-26 11:48

    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
    
    0 讨论(0)
  • 2021-01-26 11:53

    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.

    0 讨论(0)
提交回复
热议问题