MYSQL Group基于多个字段

时间:2013-10-24 05:51:07

标签: php mysql sql

我有一个相当复杂的查询,我需要一些帮助。

基本上我的表有四个字段:

Start Date,
End Date, 
Item, 
Type

我还需要获得天数

为了正确地对它们进行分组,我需要查看每一行,并检查开始日期中的日期是否连续,是否将它们分组,如果不是则进入另一组

因此,如果数据库中包含以下日期:

2013-10-23
2013-10-24
2013-10-28
2013-10-29

然后它应该返回两行

2(number of days), 2013-10-23 (startdate) ,2013-10-24 (last consecutive date) , Item, Type
2,2013-10-28,2013-10-29,Item,Type

然后将事物处理到更复杂的层次,分组需要基于项目和类型也是相同的

这就是以下数据(StartDate,Item,Type)

2013-10-23,ABC,EFG
2013-10-24,XYZ,WXY
2013-10-28,ABC,EFG
2013-10-29,ABC,EFG

然后前两个不会被分组,因为项目和/或类型彼此不相同,即使日期是连续的。

然而,最后两个会组合在一起,因为日期是连续的,而且项目和类型彼此相同,并且需要结果:

number of days  startdate   last consecutive date  Item  Type
   1            2013-10-23  2013-10-23             ABC   EFG
   1            2013-10-24  2013-10-24             XYZ   WXY
   2            2013-10-28  2013-10-29             ABC   EFG

我正在尝试用MySQL做这个,我知道我可以借助PHP进行循环,但如果可能的话,最好在MySQL中进行。

这是一个包含一些数据的SQLFiddle。 http://sqlfiddle.com/#!2/63383/1/0

3 个答案:

答案 0 :(得分:2)

SELECT COUNT(*), MIN(startdate), MAX(startdate), item, type FROM (
  SELECT   startdate, item, type,
           @group     := @group + 1 - (
                           type      <=> @last_type
                       AND item      <=> @last_item
                       AND startdate <=> @last_date + INTERVAL 1 DAY
                         ) g,
           @last_type := type,
           @last_item := item,
           @last_date := startdate
  FROM     productinfo, (
             SELECT @group     := 0,
                    @last_type := NULL,
                    @last_item := NULL,
                    @last_date := NULL
           ) init
  ORDER BY type, item, startdate
) t GROUP BY g

sqlfiddle上查看。

答案 1 :(得分:0)

试试这个:

SELECT
    DATEDIFF(MAX(startdate), MIN(startdate)) + 1 AS number_of_days,
    MIN(startdate) AS startdate,
    MAX(startdate) AS last_consecutive_date,
    item,
    type
  FROM (
    SELECT @rownum := @rownum + 1 AS row_number,
           pi.*
    FROM
      productinfo pi,
      (SELECT @rownum := 0) r
  ) mydata
GROUP BY item, type, DATE_ADD(startdate, INTERVAL -row_number DAY)
ORDER BY item, type, DATE_ADD(startdate, INTERVAL -row_number DAY)
;

根据this thread Andriy M 的回答。

SQLFiddle:SQLFiddle example

答案 2 :(得分:0)

SELECT DATEDIFF(max(enddate),min(startdate)) + 1 as days, MIN(startdate) as start, MAX(enddate) as end, type, item FROM (
  SELECT   startdate, enddate,item, type,
       @group     := @group + 1 - (
                       type      <=> @last_type
                   AND item      <=> @last_item
                   AND startdate <=> @last_date + INTERVAL 1 DAY
                     ) g,
       @last_type := type,
       @last_item := item,
       @last_date := enddate
  FROM     productinfo, (
         SELECT @group     := 0,
                @last_type := NULL,
                @last_item := NULL,
                @last_date := NULL
       ) init
  ORDER BY type, item, startdate
) t GROUP BY g order by start