补充一下:上面的例子假设有a、b、c三个站点,a站点有2个车道,b站点有3个车道,c站点有4个车道

解决方案 »

  1.   

    这个是不是每5分钟就一定有数据来啊,不来就说明有误?那可不可以直接count(车道编号) group by 站点编号假如 a、b、c三个站点,a站点有2个车道,b站点有3个车道,c站点有4个车道现在count(车道编号) group by 站点编号
    为 a站点有2个车道,b站点有2个车道,c站点有3个车道
    就说明b、c有误?你是不是这个意思哦?如果是就好办了,把数先count出来,有问题的再去找逐条时间相减不为5分钟的,然后记录相减不为5的两个时间明白?一定要写sql?
      

  2.   

    没看懂,给你个每五分钟统计的例,自己看.
    create table tb(时间 datetime , 金额 int)
    insert into tb values('2007-1-1 10:00:23' ,          8 )
    insert into tb values('2007-1-1 10:01:24' ,          4 )
    insert into tb values('2007-1-1 10:05:00' ,          2 )  
    insert into tb values('2007-1-1 10:06:12' ,          3 )
    insert into tb values('2007-1-1 10:08:00' ,          1 )
    insert into tb values('2007-1-1 10:12:11' ,          5 )
    go--时间段>=10:00:00 and 时间段<10:05:00
    select dateadd(mi,(datediff(mi,convert(varchar(10),dateadd(ss,-1,时间),120),dateadd(ss,-1,时间))/5)*5,convert(varchar(10),时间,120)) as 时间段,
           count(*) as 行数,
           sum(金额) as 总金额
    from tb
    group by dateadd(mi,(datediff(mi,convert(varchar(10),dateadd(ss,-1,时间),120),dateadd(ss,-1,时间))/5)*5,convert(varchar(10),时间,120))
    /*
    时间段                                                    行数          总金额         
    ------------------------------------------------------ ----------- ----------- 
    2007-01-01 10:00:00.000                                3           14
    2007-01-01 10:05:00.000                                2           4
    2007-01-01 10:10:00.000                                1           5
    (所影响的行数为 3 行)
    */--时间段>10:00:00 and 时间段<=10:05:00
    select dateadd(mi,(datediff(mi,convert(varchar(10),dateadd(ss,1,时间),120),dateadd(ss,1,时间))/5)*5,convert(varchar(10),时间,120)) as 时间段,
           count(*) as 行数,
           sum(金额) as 总金额
    from tb
    group by dateadd(mi,(datediff(mi,convert(varchar(10),dateadd(ss,1,时间),120),dateadd(ss,1,时间))/5)*5,convert(varchar(10),时间,120))
    /*
    时间段                                                    行数          总金额         
    ------------------------------------------------------ ----------- ----------- 
    2007-01-01 10:00:00.000                                2           12
    2007-01-01 10:05:00.000                                3           6
    2007-01-01 10:10:00.000                                1           5(所影响的行数为 3 行)
    */drop table tb
      

  3.   

    楼主是不是只是想检查一下数据量对不对?即count一下数据量对不对?能不能这样:一天24小时,可分成288个5分钟,那么理论上每个站点、每个车道的一天下来的记录数都是288的倍数,那么:select 站点, 车道, count(*)
    from TrafficTable 
    group by 站点, 车道 having count(*)%288<>0不过这里还有个风险就是上传的数据多了而不是缺了,那么也可能满足288倍数,就要去掉having子句,把数列出来除以每个站点、每个车道应该出现的记录数来检查。
      

  4.   

    那数据量还是很大的 count by group之后 假设返回的count值比应该的少一个那回去怎么确定那个少的纪录的位置阿?要是8车道的数据的话 少一条 也要自己去从2000多条数据中找阿 这还只是一个站点 要是一天缺个几个站点的数据 找起来似乎就时间很长了 
      

  5.   

    declare @t table(站点编号 varchar(10),车道编号 int,上传时间 datetime,数据值 int)
    insert into @t select'a',           1,     '2008-04-17 00:00:00',         20 union select
    'a',           2,     '2008-04-17 00:00:00',         34 union select
    'b',           1,     '2008-04-17 00:00:00',         45 union select
    'b',           2,     '2008-04-17 00:00:00',         86 union select
    'c',           1,     '2008-04-17 00:00:00',         78 union select
    'c',           2,     '2008-04-17 00:00:00',         45 union select
    'c',           3,     '2008-04-17 00:00:00',         76 union select
    'c',           4,     '2008-04-17 00:00:00',         36 union select
    'a',           1,     '2008-04-17 00:05:00',         10 union select
    'a',           2,     '2008-04-17 00:05:00',         14 union select
    'b',           1,     '2008-04-17 00:05:00',         15 union select
    'b',           2,     '2008-04-17 00:05:00',         16 union select
    'b',           3,     '2008-04-17 00:05:00',         12 union select
    'c',           1,     '2008-04-17 00:05:00',         18 union select
    'c',           2,     '2008-04-17 00:05:00',         15 union select
    'c',           3,     '2008-04-17 00:05:00',         16 
    select b.站点编号,b.上传时间 as 丢失数据时间 from(select 站点编号,max(cnt) as cnt from (select 站点编号,上传时间,count(车道编号)as cnt from @t group by 站点编号,上传时间) t
    group by 站点编号) a,(select 站点编号,上传时间,count(车道编号)as cnt from @t group by 站点编号,上传时间) bwhere a.站点编号=b.站点编号 and a.cnt<>b.cntb 在 '2008-04-17 00:00:00' 丢失了一行
    c 在 '2008-04-17 00:05:00' 丢失了一行 
      

  6.   

    我研究研究大家的方案 然后马上给分 sql学的都忘了
      

  7.   

    这个办法 数据范围缩小了。
    这是今天实际的查询结果:
    use trafficdb
    select siteid, cd, count(*) 
    from History200804  where (datatime>='2008-04-16 00:00:00' and datatime<'2008-04-17 00:00:00')
    group by siteid, cd having count(*)%288 <>01 1 205
    3 3 276
    3 1 276
    1 3 205
    1 5 205
    1 2 205
    3 2 276
    1 4 205
    3 4 276
    1 6 205
    有10个车道都缺少数据,都不只缺少一条数据,那么再回去找的话还是不好找啊 ,还要group by 站点,车道,把以站点、车道为单位的当天数据全部调出来再一条一条的找 是这样吧?
      

  8.   


    CREATE TABLE TrafficTable(站点编号 VARCHAR(10),车道编号 INT,上传时间 DATETIME,数据值 INT)
    GOINSERT INTO TrafficTable
    SELECT 'a',1,'2008-04-17 00:00:00',20 UNION ALL
    SELECT 'a',2,'2008-04-17 00:00:00',34 UNION ALL
    SELECT 'b',1,'2008-04-17 00:00:00',45 UNION ALL
    SELECT 'b',2,'2008-04-17 00:00:00',86 UNION ALL
    SELECT 'b',3,'2008-04-17 00:00:00',12 UNION ALL
    SELECT 'c',1,'2008-04-17 00:00:00',78 UNION ALL
    SELECT 'c',2,'2008-04-17 00:00:00',45 UNION ALL
    SELECT 'c',3,'2008-04-17 00:00:00',76 UNION ALL
    SELECT 'c',4,'2008-04-17 00:00:00',36 UNION ALL
    SELECT 'a',1,'2008-04-17 00:05:00',10 UNION ALL
    SELECT 'a',2,'2008-04-17 00:05:00',14 UNION ALL
    SELECT 'b',1,'2008-04-17 00:05:00',15 UNION ALL
    SELECT 'b',2,'2008-04-17 00:05:00',16 UNION ALL
    SELECT 'b',3,'2008-04-17 00:05:00',12 UNION ALL
    SELECT 'c',1,'2008-04-17 00:05:00',18 UNION ALL
    SELECT 'c',2,'2008-04-17 00:05:00',15 UNION ALL
    SELECT 'c',3,'2008-04-17 00:05:00',16 UNION ALL
    SELECT 'c',4,'2008-04-17 00:05:00',16
    GO--应该有个表保存站点和车道的表吧
    CREATE TABLE Station(站点编号 VARCHAR(10),车道编号 INT)
    GO
    INSERT INTO Station
    SELECT 'a',1 UNION ALL 
    SELECT 'a',2 UNION ALL 
    SELECT 'b',1 UNION ALL 
    SELECT 'b',2 UNION ALL 
    SELECT 'b',3 UNION ALL 
    SELECT 'c',1 UNION ALL 
    SELECT 'c',2 UNION ALL 
    SELECT 'c',3 UNION ALL
    SELECT 'c',4
    GODECLARE @begin_time DATETIME
    DECLARE @end_time DATETIMESET @begin_time = '2008-04-17 00:00:00' --你要检查的开始时间
    SET @end_time = '2008-04-17 00:10:00'   --你要检查的开始时间DECLARE @temp_time TABLE (时间 DATETIME)
    WHILE @begin_time<=@end_time
    BEGIN 
            INSERT INTO @temp_time(时间) VALUES(@begin_time)
            SET @begin_time = DATEADD(minute,5,@begin_time)
    ENDSELECT  a.站点编号
           ,a.车道编号
           ,b.上传时间
           ,b.数据值
      FROM (SELECT  a.站点编号
                   ,a.车道编号
                   ,b.时间
              FROM  Station a 
             CROSS  JOIN @temp_time b)a
      LEFT  JOIN TrafficTable b ON a.站点编号 = b.站点编号 AND a.车道编号 = b.车道编号 AND DATEDIFF(second,a.时间,b.上传时间)>=0 AND DATEDIFF(second,a.时间,b.上传时间)<300-- 那些为NULL的值就是缺少数据的值.
      

  9.   

    就是首先根据站点表和开始结束时间,得到这么多站点,路段在这段时间内应该生成时间.就是
    (SELECT  a.站点编号
                   ,a.车道编号
                   ,b.时间
              FROM  Station a 
             CROSS  JOIN @temp_time b)a
    然后与实践的记录left join就得到缺少的数据.如果刚好是5分钟,那么DATEDIFF(second,a.时间,b.上传时间)>=0 AND DATEDIFF(second,a.时间,b.上传时间)<300 可以改为a.时间 = b.上传时间
      

  10.   

    我明白意思了 确实 能比较准确的定位出缺失数据的 位置。但是有个小问题,查出来的记录有几万行,还是需要手工去定位,但是比前几位提供的方法确实定位的范围要小了。可是用肉眼去翻几万条记录去找null也比较费时,能不只把null记录的上条和下条列出来 ,中间大块连续的非null数据省略?
      

  11.   

    如果 数据真的丢失的话 数据时根本不可能存在于(select 站点编号,上传时间,count(车道编号)as cnt from @t group by 站点编号,上传时间) b中的,所以 查出来的结果 肯定是不对的
      

  12.   


    DECLARE @begin_time DATETIME
    DECLARE @end_time DATETIMESET @begin_time = '2008-04-17 00:00:00' --你要检查的开始时间
    SET @end_time = '2008-04-17 00:10:00'   --你要检查的开始时间DECLARE @temp_time TABLE (时间 DATETIME)
    WHILE @begin_time<=@end_time
    BEGIN 
            INSERT INTO @temp_time(时间) VALUES(@begin_time)
            SET @begin_time = DATEADD(minute,5,@begin_time)
    ENDSELECT * 
    FROM
    (SELECT  a.站点编号
           ,a.车道编号
           ,b.上传时间
           ,b.数据值
      FROM (SELECT  a.站点编号
                   ,a.车道编号
                   ,b.时间
              FROM  Station a 
             CROSS  JOIN @temp_time b)a
      LEFT  JOIN TrafficTable b ON a.站点编号 = b.站点编号 AND a.车道编号 = b.车道编号 AND DATEDIFF(second,a.时间,b.上传时间)>=0 AND DATEDIFF(second,a.时间,b.上传时间)<300
    )X
    WHERE 上传时间 IS NULL
      

  13.   


    SELECT *
     FROM
    (SELECT  a.站点编号
           ,a.车道编号
           ,a.时间 as 应该上传时间
           ,b.上传时间
           ,b.数据值
      FROM (SELECT  a.站点编号
                   ,a.车道编号
                   ,b.时间
              FROM  Station a 
             CROSS  JOIN @temp_time b)a
      LEFT  JOIN TrafficTable b ON a.站点编号 = b.站点编号 AND a.车道编号 = b.车道编号 AND DATEDIFF(second,a.时间,b.上传时间)>=0 AND DATEDIFF(second,a.时间,b.上传时间)<300
    )X
    WHERE 上传时间 IS NULL
      

  14.   

    多谢xiaoliaoyun !我知道怎么改了