我想列出按月分组以及在下一栏中完成课程的剩余天数。课程有10天。
示例数据
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
首选输出
| Name | Month | Attended | Remaining|
| Sandy| May | 2 | 8 |
| Candy| May | 2 | 8 |
| Candy| June | 1 | 7 |
如果我使用GROUP BY DATE_FORMAT(日期,'%Y%m'),名称并尝试进行计算则不起作用。
答案 0 :(得分:0)
您需要两种不同的聚合:
这有点繁琐,所以现在是时候做一些测试驱动的查询设计(TDQD)。
问题中的表格是匿名的 - 这是一种常见且令人不快的情况。因此,该表从此为CourseAttendance
,数据中显示了三列(ID,名称,日期)。
假设表达式DATE_FORMAT(date, '%Y-%m')
在语法上有效,并且Date
和Month
作为列名称都不会导致问题,那么:
SELECT DATE_FORMAT(Date, '%Y-%m') AS Month,
Name,
COUNT(*) AS NumDays
FROM CourseAttendance
GROUP BY Month, Name
这应该产生:
Month Name NumDays
2015-05 Sandy 2
2015-05 Candy 2
2015-06 Candy 1
这次,汇总必须超过所有日期小于或等于转换月份值:
SELECT D.Month, D.Name, SUM(C.NumDays) AS TotDays
FROM (SELECT DISTINCT DATE_FORMAT(Date, '%Y-%m') AS Month, Name
FROM CourseAttendance
) AS D
JOIN (SELECT DATE_FORMAT(Date, '%Y-%m') AS Month,
Name,
COUNT(*) AS NumDays
FROM CourseAttendance
GROUP BY Month, Name
) AS C
ON C.Month <= D.Month AND C.Name = D.Name
GROUP BY D.Month, D.Name
这应该给出输出:
Month Name NumDays
2015-05 Sandy 2
2015-05 Candy 2
2015-06 Candy 3
前两个结果表需要在Month和Name上连接,以产生结果:
SELECT A.Name, A.Month, A.NumDays AS Attended, (10 - B.TotDays) AS Remaining
FROM (SELECT DATE_FORMAT(Date, '%Y-%m') AS Month,
Name,
COUNT(*) AS NumDays
FROM CourseAttendance
GROUP BY Month, Name
) AS A
JOIN (SELECT D.Month, D.Name, SUM(C.NumDays) AS TotDays
FROM (SELECT DISTINCT DATE_FORMAT(Date, '%Y-%m') AS Month, Name
FROM CourseAttendance
) AS D
JOIN (SELECT DATE_FORMAT(Date, '%Y-%m') AS Month,
Name,
COUNT(*) AS NumDays
FROM CourseAttendance
GROUP BY Month, Name
) AS C
ON C.Month <= D.Month AND C.Name = D.Name
GROUP BY D.Month, D.Name
) AS B
ON A.Month = B.Month AND A.Name = B.Name
ORDER BY A.Name, A.Month
这应该输出如下:
Name Month Attended Remaining
Candy 2015-05 2 8
Candy 2015-06 1 7
Sandy 2015-05 2 8
如果需要,您可以将月份值伪装成月份名称。如果您想在月份内使用月份和名称等,也可以获取排序顺序