我有一个表格,其中包含以下格式的数据:
id name cnt1 created_on
'1','uac','116','2014-09-06 17:16:29'
'2','uac','116','2014-09-06 17:17:06'
'3','uac','90','2014-09-06 21:53:34'
'4','uac','100','2014-08-06 21:53:34'
'5','uac','1','2014-07-06 21:53:34'
'6','uac','2','2014-07-26 21:53:34'
'7','uac','3','2014-09-01 21:53:34'
'8','uac','4','2014-09-02 21:53:34'
'9','uac','5','2014-09-03 21:53:34'
'10','uac','6','2014-09-04 21:53:34'
'11','uac','7','2014-09-05 21:53:34'
'12','uac','8','2014-09-07 21:53:34'
'13','uac','9','2014-09-08 21:53:34'
我希望给定日期范围的数据应分组为1.每周2.每月 此外,我希望在一周或一个月内获得最后一周或每月数据的数据。例如 如果我每月获得数据,我应该得到以下输出:
'6','uac','1','2014-07-26 21:53:34'
'4','uac','100','2014-08-06 21:53:34'
'13','uac','116','2014-09-08 21:53:34'
我试过了这个查询
SELECT id,name,cnt1,created_on
FROM qa_dashboard.project_qa_coverage_detail
GROUP BY year(created_on), month(created_on);
但是这给了我以下输出
'5','uac','1','2014-07-06 21:53:34'
'4','uac','100','2014-08-06 21:53:34'
'1','uac','116','2014-09-06 17:16:29'
请帮忙
答案 0 :(得分:1)
您实际上并不想要group by
查询。您想获得每组的最后一行。以下是使用not exists
的方法:
SELECT cd.*
FROM qa_dashboard.project_qa_coverage_detail cd
WHERE NOT EXISTS (SELECT 1
FROM qa_dashboard.project_qa_coverage_detail cd2
WHERE year(cd2.created_on) = year(cd.created_on) and
month(cd2.created_on) = month(cd.created_on) and
cd2.created_on > cd.created_on
) ;
这就是说,实质上是:“从表格中获取所有行,其中没有其他行具有相同的年份和月份以及更近的created_on
日期。”这是一种说法“让我每个月都排在最后一行。”的幻想。
EDIT;
如果您想要月份的第一个和最后一个日期的值,请改用join
方法:
select cd.*, cdsum.minco as first_created_on
from qa_dashboard.project_qa_coverage_detail cd join
(select year(cd2.created_on) as yr, month(cd2.created_on) as mon,
min(cd2.created_on) as minco, max(cd2.created_on) as maxco
from qa_dashboard.project_qa_coverage_detail cd2
group by year(cd2.created_on), month(cd2.created_on)
) cdsum
on cd.created_on = cd2.maxco;
答案 1 :(得分:1)
非常确定这会为您提供预期的输出:
上个月:
select t.*
from tbl t
join (select max(created_on) as last_for_month
from tbl
group by year(created_on), month(created_on)) v
on t.created_on = v.last_for_month
除非你说你期望:
'6','uac','1','2014-07-26 21:53:34'
我认为你真正想要的是:
'6','uac','2','2014-07-26 21:53:34'
(根据您提供的样本数据)
<强>小提琴:强> http://sqlfiddle.com/#!9/faaa3/4/0
持续一周:
select t.*
from tbl t
join (select max(created_on) as last_for_week
from tbl
group by year(created_on), week(created_on)) v
on t.created_on = v.last_for_week
根据您的评论,如果您想要本月最后一个的最后一个值和最后一个ID,但是该月的第一个是cnt1的值,请使用以下内容(将month()更改为week()你想要相同但是一周):
select v.id, v2.first_created_on, v.cnt1
from (select t.id, t.created_on, t.cnt1
from tbl t
join (select max(created_on) as last_created_on
from tbl
group by year(created_on), month(created_on)) v
on t.created_on = v.last_created_on) v
join (select min(created_on) as first_created_on
from tbl
group by year(created_on), month(created_on)) v2
on year(v.created_on) = year(v2.first_created_on)
and month(v.created_on) = month(v2.first_created_on)
<强>小提琴:强> http://sqlfiddle.com/#!9/faaa3/5/0
输出:
| ID | FIRST_CREATED_ON | CNT1 |
|----|----------------------------------|------|
| 4 | August, 06 2014 21:53:34+0000 | 100 |
| 6 | July, 06 2014 21:53:34+0000 | 2 |
| 13 | September, 01 2014 21:53:34+0000 | 9 |
答案 2 :(得分:0)
这看起来像预期的输出,每年和每月一行。您已将created_on
指定为SELECT列表中的表达式,因此您将从每个组中的一行获取created_on
列中的值。
如果您只想在输出中输入年份和月份,则需要在SELECT列表中使用不同的表达式。例如,
DATE_FORMAT(created_on,'%Y-%m') AS yyyy_mm
您可以使用相同的表达式GROUP BY子句,而不是两个单独的表达式。
作为另一种选择,您可以使用SELECT列表中的YEAR(created_on), MONTH(created_on)
。
要按周“分组”行,您可以使用WEEK(created_on)
代替MONTH(created_on)
。
要返回每个组的“last”行,正常模式是使用内联视图和JOIN操作。例如:
SELECT t.id
, t.project
, t.total_tc
, t.created_on
FROM qa_dashboard.project_qa_coverage_detail t
JOIN ( SELECT MAX(r.created_on)
FROM qa_dashboard.project_qa_coverage_detail r
GROUP BY DATE_FORMAT(r.created_on,'%Y-%m')
) s
ON s.created_on = t.created
请注意,如果有两个(或更多)行具有相同的created_on
值,则此查询可能会为该组返回多行。