mysql - distinct items per month per distinct group

时间:2015-05-04 19:44:49

标签: php mysql

Hello and thank you in advance for taking the time to read.

I have a table with the following fields:

id int(11), facility char(4), item varchar(8), dte date

For example:

266588, STAL, GROGOORI, 2015-01-03
266589, STAL, GROGONRY, 2015-01-03
266590, STAM, GROGOORI, 2015-02-01
...

I am trying to get to total number of unique items per facility each month for a calendar year. So the desired output looks something like:

fac | jan | feb | ... | dec |
abc | 100 | 107 | ... | 113 |
def |  93 |  90 | ... | 100 |
... 

I currently achieve this (in php) with multiple queries. an initial one to get the list of facilities then 1 query for each facility returned which gives the monthly data.

Although this cludge worked fine initially the obvious overhead for my lameness is being felt now as I'm doing hundreds of queries.

I worked out a query to return total number of items each month per facility using some CASE WHEN logic such as:

select distinct binary(facility) as a,
    , sum(case when month(dte) = 1 then 1 else 0 end) Jan
    , sum(case when month(dte) = 2 then 1 else 0 end) Feb
    ...
from test where year(dte) = 2015 group by a

However, I've fallen flat while trying to convert that to only unique items. I don't believe CASE WHEN is going to get me there, I only used this to help illustrate the goal.

So, what I'm really looking for is a single database hit to achieve the list. Any insights are appreciated!

2 个答案:

答案 0 :(得分:1)

SELECT `facility`
   , SUM(IF(the_month = 1, dItems, 0)) AS `Jan`
   , ...
FROM (
   SELECT `facility`, MONTH(`dte`) AS `the_month`, COUNT(DISTINCT `item`) AS `dItems`
   FROM `the_table`
   GROUP BY `facility`, `the_month`
) AS subQ
GROUP BY `facility`
;

答案 1 :(得分:0)

您可以使用子查询:

select facility, 
  count(distinct Jan) as 'Jan',
  count(distinct Feb) as 'Feb',
  count(distinct Mar) as 'Mar'
from (
  select facility,
    case when month(dte) = 1 then item else null end as 'Jan',
    case when month(dte) = 2 then item else null end as 'Feb',
    case when month(dte) = 3 then item else null end as 'Mar'
  from test 
  where year(dte) = 2015
) as q
group by facility