如何从每周,每月从给定日期范围组的mysql获取数据

时间:2014-09-06 17:54:07

标签: mysql sql

我有一个表格,其中包含以下格式的数据:

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'

请帮忙

3 个答案:

答案 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值,则此查询可能会为该组返回多行。