MySQL获取行中日期的周期数

时间:2015-09-15 14:34:08

标签: mysql

我有一个MySQL表,类似于这个例子:

c_id    date    value
66  2015-07-01  1
66  2015-07-02  777
66  2015-08-01  33
66  2015-08-20  200
66  2015-08-21  11
66  2015-09-14  202
66  2015-09-15  204
66  2015-09-16  23
66  2015-09-17  0
66  2015-09-18  231

我需要得到的是日期在一行的时间段。我没有固定的开始或结束日期,可以有任何。

例如:2015-07-01 - 2015-07-02是一个priod,2015-08-01是第二期,2015-08-20 - 2015-08-21是第三期和2015-09-14 - 2015-09-18作为第四期。所以在这个例子中有四个时期。

SELECT 
SUM(value) as value_sum,
... as period_count
FROM my_table 
WHERE cid = 66

不能整天想出来...... Thx。

4 个答案:

答案 0 :(得分:3)

我没有足够的声誉对上述答案发表评论。

如果你需要的只是分数数,那么你可以简单地改写你的问题:"有多少条目有日期D,这样日期D-1 DAY没有条目?&#34 ;

在这种情况下,这就是您所需要的:

SELECT 
    COUNT(*) as PeriodCount
FROM
    `periods`
WHERE
    DATE_ADD(`date`, INTERVAL - 1 DAY) NOT IN (SELECT `date` from `periods`);

在PHP中,只需选择" PeriodCount"第一行的列。

你让我研究了一些疯狂的存储过程方法,直到澄清:P

答案 1 :(得分:2)

我应该得到应有的火焰,但无论如何,请考虑以下......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(date DATE NOT NULL PRIMARY KEY
,value INT NOT NULL
);

INSERT INTO my_table VALUES
('2015-07-01',1),
('2015-07-02',777),
('2015-08-01',33),
('2015-08-20',200),
('2015-08-21',11),
('2015-09-14',202),
('2015-09-15',204),
('2015-09-16',23),
('2015-09-17',0),
('2015-09-18',231);

SELECT x.*
     , SUM(y.value) total
  FROM 
     ( SELECT a.date start
            , MIN(c.date) end 
         FROM my_table a
         LEFT 
         JOIN my_table b 
           ON b.date = a.date - INTERVAL 1 DAY 
         LEFT 
         JOIN my_table c   
           ON c.date >= a.date
         LEFT 
         JOIN my_table d 
           ON d.date = c.date + INTERVAL 1 DAY
        WHERE b.date IS NULL 
          AND c.date IS NOT NULL
          AND d.date IS NULL
        GROUP 
           BY a.date
     ) x
  JOIN my_table y
    ON y.date BETWEEN x.start AND x.end
 GROUP 
    BY x.start;

+------------+------------+-------+
| start      | end        | total |
+------------+------------+-------+
| 2015-07-01 | 2015-07-02 |   778 |
| 2015-08-01 | 2015-08-01 |    33 |
| 2015-08-20 | 2015-08-21 |   211 |
| 2015-09-14 | 2015-09-18 |   660 |
+------------+------------+-------+
4 rows in set (0.00 sec) -- <-- This is the number of periods

答案 2 :(得分:2)

有一种更简单的方法,请参阅此处SQLfiddle

SELECT min(date) start,max(date) end,sum(value) total FROM 
 (SELECT @i:=@i+1 i,
         ROUND(Unix_timestamp(date)/(24*60*60))-@i diff,
         date,value 
  FROM tbl, (SELECT @i:=0)n WHERE c_id=66 ORDER BY date) t 
GROUP BY diff

此序号和日期值之间相同差异select组。

修改

正如草莓所说的那样,我的计划中存在一个缺陷,即一个月的变化或者明年的变化。 unix_timestamp()函数可以解决这个问题:它会返回1970-1-1后的秒数,因此将此数字除以24*60*60即可获得自该特定日期以来的天数。其余的很简单......

如果您需要计数,正如您上次发表的评论所述,您甚至可以simpler执行此操作:

SELECT count(distinct diff) period_count FROM 
 (SELECT @i:=@i+1 i,
         ROUND(Unix_timestamp(date)/(24*60*60))-@i diff,
         date,value 
  FROM tbl,(SELECT @i:=0)n WHERE c_id=66 ORDER BY date) t 

答案 3 :(得分:0)

TNX。 @ cars10解决方案在MySQL中运行,但无法设法在PHP中获得周期计数。它返回0.让它工作到@jarkinstall tnx。所以我的最终选择看起来像这样:

SELECT sum(coalesce(count_tmp,coalesce(count_reserved,0))) as sum ,(SELECT COUNT(*) FROM my_table WHERE cid='.$cid.' AND DATE_ADD(日期, INTERVAL - 1 DAY) NOT IN (SELECT date from my_table WHERE cid='.$cid.' AND coalesce(count_tmp,coalesce(count_reserved,0))>0)) as periods ,count(*) as count ,(min(date)) as min_date ,(max(date)) as max_date FROM my_table WHERE cid=66 AND coalesce(count_tmp,coalesce(count_reserved,0))>0 ORDER BY date;