Sql以块的形式检索数据

时间:2015-08-11 11:31:21

标签: sql sql-server

我坚持使用sql数据检索。我有数据库,其中包含块或组中的数据,如一种类型的10条记录,然后是其他类型的10条记录,然后再次输入第一类记录。

如下表

id  time   group
=================
1   12:30  xyz
2   12:40  xyz
3   12:50  null
4   1:00   null
5   1:10   abc
6   1:20   abc
7   1:30   xyz
8   1:40   xyz

所以在上面的例子中我有三个组,如xyz,null,abc。我需要花时间在xyz,null和abc个人身上。

我想要

id  time  group
==================
1   20    xyz              
2   30    null
3   20    abc

我希望它有意义,就像总时间花费是70。 提前致谢

3 个答案:

答案 0 :(得分:0)

这很复杂。您需要识别组。你有两种方法可以做到这一点。一种方法是使用lead()。另一种方法是识别组并使用该信息进行分组。这是第二种方法,使用行号的差异来获取组。

这将获取每组记录的信息:

select group, min(time) as firsttime, max(time) as lasttime
from (select t.*,
             (row_number() over (order by id) -
              row_number() over (order by id, group)
             ) as grp
      from table t
     ) t
group by group, grp;

您最终想要的是另一个级别的聚合:

select row_number() over (order by min(id)), group,
       sum(datediff(minute, firsttime, lasttime)) as time
from (select group, min(time) as firsttime, max(time) as lasttime,
             min(id) as id
      from (select t.*,
                   (row_number() over (order by id) -
                    row_number() over (order by id, group)
                   ) as grp
            from table t
           ) t
      group by group, grp
     ) t
group by group;

注意:group是列的糟糕名称,因为它是SQL保留字。我假设真实姓名不同。

答案 1 :(得分:0)

您可以将此表连接到自身,以将每条记录加入同一组中的下一条记录。这将允许您计算花费的时间:

SELECT 
  MIN(t1.id) as id, SUM(t2.time - t1.time) as time, group
FROM myTable t1 LEFT JOIN 
     myTable t2 ON t1.group = t2.group and t2.id = t1.id + 1
GROUP BY group

这里假设您的ID字段没有间隙。

如果ID字段有间隙,则需要将查询更改为:

 SELECT 
     MIN(t1.id) AS id, SUM(t2.time - t1.time) as time, group
    FROM myTable t1 LEFT JOIN 
         myTable t2 ON t1.group = t2.group AND t1.id < t2.id
         NOT EXISTS 
            (SELECT * FROM myTable 
             WHERE id > t1.id and id < t2.id)
 GROUP BY group

答案 2 :(得分:0)

IF OBJECT_ID('tempdb..#myTable') IS NOT NULL
    DROP TABLE #myTable;

SELECT 
    id, time, grp
INTO 
    #myTable
FROM 
    (VALUES
    (1, CAST('12:30' AS time), 'xyz'),
    (2, '12:40', 'xyz'),
    (3, '12:50', NULL),
    (4, '13:00', NULL),
    (5, '13:10', 'abc'),
    (6, '13:20', 'abc'),
    (7, '13:30', 'xyz'),
    (8, '13:40', 'xyz')
    ) dt(id, time, grp)

SELECT 
    MIN(t1.id) as id, 
    SUM(DATEDIFF(MINUTE, t1.time, t2.time)) as time, 
    t1.grp
FROM 
    #myTable t1 LEFT JOIN 
    #myTable t2 ON ISNULL(t1.grp, 1) = ISNULL(t2.grp, 1) and t2.id = t1.id + 1
GROUP BY 
    t1.grp
ORDER BY 
    1