如何计算mysql中表中日期之间的最大粒度(或间隔)

时间:2016-03-11 04:31:04

标签: mysql

我有3列的表,如

NAME     DATE_TIME                 AMOUNT
T1       2012:10:01  12:15:00        200
T1       2012:10:01  12:30:00        300
T1       2012:10:02  01:00:00        400
T1       2012:10:02  01:15:00        500
T1       2012:10:03  04:00:00        600
T1       2012:10:03  05:00:00        700
T2       2013:12:31  22:30:00        3838
T2       2013:12:31  23:00:00        7272
T2       2013:12:31  23:30:00        891
T2       2013:12:31  23:45:00        288

在表T1值中,最大间隔为15分钟,对于T2,最大间隔为30分钟,输出为

NAME Granularity / max.interval T1 15(分钟) T2 30(分钟)

提前致谢

1 个答案:

答案 0 :(得分:1)

这是一个完整演示的解决方案。

-- SQL needed
SELECT 
    NAME, Granularity, cnt
FROM 
(
    SELECT 
        NAME, Granularity, COUNT(*) cnt
    FROM
    (
        SELECT 
            *,
            IF(@last_name IS NULL OR NAME != @last_name OR DATE(@last_dt) != DATE(DATE_TIME),
               0, TIMESTAMPDIFF(MINUTE, @last_dt, DATE_TIME))AS Granularity,
            @last_name:=NAME,
            @last_dt:=DATE_TIME
        FROM t1 JOIN (SELECT @last_dt:=NULL, @last_name:=NULL) v
    ) t
    WHERE t.Granularity > 0 
    GROUP BY NAME, Granularity
) tt
WHERE 
    (NAME, cnt) IN 
    (
        SELECT NAME, MAX(cnt) max_cnt
        FROM
        (
            SELECT 
                NAME, Granularity, COUNT(*) cnt
            FROM
            (
                SELECT 
                    *,
                    IF(@last_name IS NULL OR NAME != @last_name OR DATE(@last_dt) != DATE(DATE_TIME),
                       0, TIMESTAMPDIFF(MINUTE, @last_dt, DATE_TIME))AS Granularity,
                    @last_name:=NAME,
                    @last_dt:=DATE_TIME
                FROM t1 JOIN (SELECT @last_dt:=NULL, @last_name:=NULL) v
            ) t
            WHERE t.Granularity > 0 
            GROUP BY NAME, Granularity
        ) ttt
        GROUP BY NAME
    );

以下是使用您提供的数据的完整演示。

SQL:

-- data
create table t1(NAME char(20),  DATE_TIME datetime, AMOUNT int);
insert into t1 values
('T1',       '2012:10:01  12:15:00',        200),
('T1',       '2012:10:01  12:30:00',        300),
('T1',       '2012:10:02  01:00:00',        400),
('T1',       '2012:10:02  01:15:00',        500),
('T1',       '2012:10:03  04:00:00',        600),
('T1',       '2012:10:03  05:00:00',        700),
('T2',       '2013:12:31  22:30:00',        3838),
('T2',       '2013:12:31  23:00:00',        7272),
('T2',       '2013:12:31  23:30:00',        891),
('T2',       '2013:12:31  23:45:00',        288);
SELECT * FROM t1;




-- SQL needed
SELECT 
    NAME, Granularity, cnt
FROM 
(
    SELECT 
        NAME, Granularity, COUNT(*) cnt
    FROM
    (
        SELECT 
            *,
            IF(@last_name IS NULL OR NAME != @last_name OR DATE(@last_dt) != DATE(DATE_TIME),
               0, TIMESTAMPDIFF(MINUTE, @last_dt, DATE_TIME))AS Granularity,
            @last_name:=NAME,
            @last_dt:=DATE_TIME
        FROM t1 JOIN (SELECT @last_dt:=NULL, @last_name:=NULL) v
    ) t
    WHERE t.Granularity > 0 
    GROUP BY NAME, Granularity
) tt
WHERE 
    (NAME, cnt) IN 
    (
        SELECT NAME, MAX(cnt) max_cnt
        FROM
        (
            SELECT 
                NAME, Granularity, COUNT(*) cnt
            FROM
            (
                SELECT 
                    *,
                    IF(@last_name IS NULL OR NAME != @last_name OR DATE(@last_dt) != DATE(DATE_TIME),
                       0, TIMESTAMPDIFF(MINUTE, @last_dt, DATE_TIME))AS Granularity,
                    @last_name:=NAME,
                    @last_dt:=DATE_TIME
                FROM t1 JOIN (SELECT @last_dt:=NULL, @last_name:=NULL) v
            ) t
            WHERE t.Granularity > 0 
            GROUP BY NAME, Granularity
        ) ttt
        GROUP BY NAME
    );

输出:

mysql> SELECT * FROM t1;
+------+---------------------+--------+
| NAME | DATE_TIME           | AMOUNT |
+------+---------------------+--------+
| T1   | 2012-10-01 12:15:00 |    200 |
| T1   | 2012-10-01 12:30:00 |    300 |
| T1   | 2012-10-02 01:00:00 |    400 |
| T1   | 2012-10-02 01:15:00 |    500 |
| T1   | 2012-10-03 04:00:00 |    600 |
| T1   | 2012-10-03 05:00:00 |    700 |
| T2   | 2013-12-31 22:30:00 |   3838 |
| T2   | 2013-12-31 23:00:00 |   7272 |
| T2   | 2013-12-31 23:30:00 |    891 |
| T2   | 2013-12-31 23:45:00 |    288 |
+------+---------------------+--------+
10 rows in set (0.00 sec)
    ...
+------+-------------+-----+
| NAME | Granularity | cnt |
+------+-------------+-----+
| T1   |          15 |   2 |
| T2   |          30 |   2 |
+------+-------------+-----+
2 rows in set (0.00 sec)