mysql - Group By Month And Show Total Days Remaining -


i want list grouped month , days remaining complete course in next column. course has 10 days.

example data

id name date  1 sandy 2015-05-06  2 candy 2015-05-06  3 sandy 2015-05-28  4 candy 2015-05-29 5 candy 2015-06-01 

preferred output

| name | month | attended | remaining| | sandy| may   |   2      |     8    | | candy| may   |   2      |     8    | | candy| june  |   1      |     7    | 

if use group date_format(date, '%y%m'), name , try calculation not work.

you need 2 different aggregates:

  1. the number of days attended in current month given user.
  2. the number of days attended in months , including current month given user.

that's tad fiddly, 'tis time test-driven query design (tdqd).

the table in question anonymous — that's such common , irritating situation. so, table henceforth courseattendance, 3 columns shown in data (id, name, date).

number of days attended user in specific month

assuming expression date_format(date, '%y-%m') syntactically valid, , neither date nor month column name causes problems, then:

select date_format(date, '%y-%m') month,        name,        count(*) numdays   courseattendance  group month, name 

this should produce:

month     name      numdays 2015-05   sandy     2 2015-05   candy     2 2015-06   candy     1 

number of days attended user , including specific month

this time, aggregate has on dates less or equal converted month value:

select d.month, d.name, sum(c.numdays) totdays   (select distinct date_format(date, '%y-%m') month, name           courseattendance        ) d   join (select date_format(date, '%y-%m') month,                name,                count(*) numdays           courseattendance          group month, name        ) c     on c.month <= d.month , c.name = d.name  group d.month, d.name 

this should give output:

month     name      numdays 2015-05   sandy     2 2015-05   candy     2 2015-06   candy     3 

assembling final result

the 2 previous result tables need joined on month , name, yield result:

select a.name, a.month, a.numdays attended, (10 - b.totdays) remaining   (select date_format(date, '%y-%m') month,                name,                count(*) numdays           courseattendance          group month, name        )   join (select d.month, d.name, sum(c.numdays) totdays           (select distinct date_format(date, '%y-%m') month, name                   courseattendance                ) d           join (select date_format(date, '%y-%m') month,                        name,                        count(*) numdays                   courseattendance                  group month, name                ) c             on c.month <= d.month , c.name = d.name          group d.month, d.name        ) b     on a.month = b.month , a.name = b.name  order a.name, a.month 

this should give output like:

name      month      attended     remaining candy     2015-05    2            8 candy     2015-06    1            7 sandy     2015-05    2            8 

you can fettle month value month name if need to. can fettle sort order if want month , name within month, etc.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -