Sql表对值进行子分组

时间:2015-01-17 11:02:46

标签: sql-server database grouping partitioning

我有车辆跟踪数据,我想创建车辆停止报告。帮我写那个sql查询。实际数据和结果数据分别如表1和表2所示。

enter image description here enter image description here

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,这是一些工作声明

declare @t TABLE(id INT, dt DATETIME, sp int)

INSERT INTO @t VALUES(1, '2015-01-17 12:00:05', 12)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:06', 0)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:07', 0)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:08', 0)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:09', 5)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:10', 8)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:11', 0)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:12', 0)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:13', 0)
INSERT INTO @t VALUES(1, '2015-01-17 12:00:14', 7)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:05', 10)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:06', 0)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:07', 0)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:08', 0)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:09', 12)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:10', 0)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:11', 0)
INSERT INTO @t VALUES(2, '2015-01-17 12:00:12', 10)




;
WITH    cte1
          AS ( SELECT   a.id ,
                        a.dt AS stdt ,
                        b.dt AS endt ,
                        a.sp ,
                        a.rn
               FROM     ( SELECT    * ,
                                    1
                                    + ROW_NUMBER() OVER ( PARTITION BY id ORDER BY dt ) AS n ,
                                    ROW_NUMBER() OVER ( ORDER BY GETDATE() ) AS rn
                          FROM      @t t1
                        ) a
                        LEFT JOIN ( SELECT  * ,
                                            ROW_NUMBER() OVER ( PARTITION BY id ORDER BY dt ) AS n
                                    FROM    @t t1
                                  ) b ON b.id = a.id
                                         AND b.n = a.n
             ),
        cte2
          AS ( SELECT   t1.id ,
                        t1.stdt ,
                        ISNULL(t1.endt, GETDATE()) AS endt ,
                        t1.sp ,
                        t1.rn ,
                        SUM(t2.sp) AS sum
               FROM     cte1 t1
                        INNER JOIN cte1 t2 ON t1.rn >= t2.rn
               GROUP BY t1.id ,
                        t1.stdt ,
                        t1.endt ,
                        t1.sp ,
                        t1.rn
             )
    SELECT  id ,
            MIN(stdt) ,
            MAX(stdt) ,
            DATEDIFF(ss, MIN(stdt), MAX(stdt)) 
    FROM    cte2
    WHERE   sp = 0
    GROUP BY id ,
            SUM

这是结果

1   2015-01-17 12:00:06.000 2015-01-17 12:00:08.000 2
1   2015-01-17 12:00:11.000 2015-01-17 12:00:13.000 2
2   2015-01-17 12:00:06.000 2015-01-17 12:00:08.000 2
2   2015-01-17 12:00:10.000 2015-01-17 12:00:11.000 1

您有车辆1 12:06 to 12:08的结果。但我真的认为结果应该是12:06 to 12:09。如果是这样,只需更改

SELECT  id ,
                MIN(stdt) ,
                MAX(stdt) ,
                DATEDIFF(ss, MIN(stdt), MAX(stdt))
        FROM    cte2
        WHERE   sp = 0
        GROUP BY id ,
                SUM

SELECT  id ,
            MIN(stdt) ,
            MAX(endt) ,
            DATEDIFF(ss, MIN(stdt), MAX(endt))
    FROM    cte2
    WHERE   sp = 0
    GROUP BY id ,
            SUM