如有这样一个表ttt
times                   c1   c2
2007-1-30 0:00:01       1.1  2.2
2007-1-30 0:05:12       1.4  4.4
2007-1-30 0:07:01       2.1  3.2
2007-1-30 0:11:06       1.2  2.3
........times时间间隔无规律,比如查出来一天的记录有2000条,我现在只要其中200条,用做时间曲线,该有什么方法呢,分不够再加的,谢谢

解决方案 »

  1.   

    select r,e.* from (select rownum r,times,c1,c2 from (
    select times,c1,c2 from ttt order by times desc)) e
    where r<201;
      

  2.   

    是要随机获取200条吗?如果是的话,下面的语句应该就可以
    select column,row_number() over(order by dbms_random.value) n from tablename 
    where rownum<=200
      

  3.   

    时间范围从0点到23点59分那不就是一天吗select r,e.* from (select rownum r,times,c1,c2 from (
    select times,c1,c2 from ttt where to_char(times,'yyyy-mm-dd')='2007-1-30' order by times desc)) e
    where r<201;
      

  4.   

    lz你说的200点,怎么分布还是随机选取?
    若是随机选取,选取的原则是什么?这个原则决定了where子句怎么写
      

  5.   

    不是舍掉前面也不是舍掉后面,更不能随即取,有一种思路,可以把记录查出来排序,然后间隔取,比如共有2000条,在排序后的结果集里每隔10条取一行记录生成新的结果集,,(where rownum %10 =0)??有这种用法么。如果能解决同时又带来了新的问题,如果数据源记录不是2000条,而是count(*),又该怎么写间隔取啊
      

  6.   

    可以考虑把
    where r<201;改成
    where r%10=0;试试的,看看取出来的数据怎样?
      

  7.   

    报错,invalid character,在r%10这个地方
      

  8.   

    yyy21说的太对了,就是要这个,有人知道答案么
      

  9.   

    两种思路都行,一种是我说的间隔取数,另一种是yyy21说的先用200等分时间刻度,取最近的值
      

  10.   

    1、如果200点时刻固定,生成临时时刻表,关联源表,如果关联到纪录,则取本条C1,C2值,如果没有,则用DECODE和LAG函数取前一条纪录的C1,C2。
    2、如果是根据最大时刻和最小时刻生成200个,先自身关联生成200完整时刻,再关联源表。
      

  11.   

    对,mod(r,10)=0就可以了,不过yyy21说的方法更准确,实现起来还是很复杂的,我目前还没有写出来,55
      

  12.   

    这个例子类似,可参考
    http://community.csdn.net/Expert/topic/5294/5294343.xml?temp=.4365808
      

  13.   

    呵呵最后应该是改成mod(r,10)=0
      

  14.   

    SELECT (TRUNC(SYSDATE) + period / 2000) AS ptime, sc1, sc2 // 还原成时间格式
    FROM
    (
      SELECT period, SUM(c1) AS sc1, SUM(c2) AS sc2  // 合并求平均值
      FROM
      (
       SELECT TRUNC(((times - TRUNC(SYSDATE)) * 2000)) AS period, c1, c2 FROM tst WHERE times >= TRUNC(SYSDATE)  // 分成2000个时段
      )
      GROUP BY period
    )
      

  15.   

    偶也是初级菜鸟,呵呵!写出点不知道对不对:
    select A.* from A,(select floor(count(*)/200) as step from A) B 
    where mod(A.rownum,B.step) = 0其中A是已经查询出的那一天中的2000对条记录
      

  16.   

    --->cctv13():
    “where mod(A.rownum,B.step) = 0”这里A.rownum不能这样用,rownum不是表的属性列,这样写肯定存在问题;再者,rownum随着order或者group子句的不同会不一样,你可以试一下,除了MOD 1,ROWNUM MOD 任何大于1的数都将返回空记录集。
      

  17.   

    SELECT AVG(c1) AS avg_of_c1, AVG(c2) AS avg_of_c2, theYear, theMonth, theday, theOrder FROM 
    (SELECT DATEPART(yy, times) AS theYear, DATEPART(mm, times) AS theMonth, DATEPART(dd, times) AS theday, (DATEPART(hh, times) * 24 * 60 * 60 + DATEPART(MM, times) * 60 * 60 + DATEPART(ss, times) * 60)/ 200 AS theOrder, * FROM ttt) 
    GROUP BY theYear, theMonth, theday, theOrder设计思路:把一天按时间均分200个时间间隔,然后将每个时间间隔中的c1,c2取平均值。
    返回值:
    -avg_of_c1,avg_of_c2:分别是该时间间隔中c1,c2的平均值;
    -theYear, theMonth, theday:是记录所在的年、月,日;
    -theOrder:是一天的200个时间间隔次序中,所在的时间次序的位置。
      

  18.   

    抱歉哦,上面的SQL有地方写错了,应是这样的:SELECT AVG(c1) AS avg_of_c1, AVG(c2) AS avg_of_c2, theYear, theMonth, theday, 
          theOrder
    FROM (SELECT DATEPART(yy, times) AS theYear, DATEPART(mm, times) AS theMonth, 
                  DATEPART(dd, times) AS theday, (DATEPART(hh, times) 
                  * 60 * 60 + DATEPART(MM, times) * 60 + DATEPART(ss, times)) 
                  / (24 * 60 * 60 / 200) AS theOrder, *
            FROM ttt) 
    GROUP BY theYear, theMonth, theday, theOrder
      

  19.   

    把今天记录抽出来,重新做张TABEL,新TABLE加个流水号字段 ++,然后就 MOD一把就可以了
      

  20.   

    create table test1(xx int);declare
    i int;
    x int;
    begin
    for i in 1 .. 200 loop
    x :=  (86400/200)*i;
    insert into test1(xx) values(x);
    end loop;
    end;select yy.标准点,to_char(yy.采集点,'yyyy-MM-dd HH24:MI:SS'),yy.时间差 from (select abs(to_number(to_char(tt.times,'sssss'))-te.xx) 时间差,te.xx 标准点,tt.times 采集点 from ttt tt ,test1 te)yy,(select min(时间差) 最近点,标准点 from (select abs(to_number(to_char(tt.times,'sssss'))-te.xx) 时间差,te.xx 标准点,tt.times 采集点 from ttt tt ,test1 te) group by 标准点) zz where yy.时间差 = zz.最近点 order by yy.标准点在查询中没有加日期范围,需要加上.
      

  21.   

    --->cctv13():
    “where mod(A.rownum,B.step) = 0”这里A.rownum不能这样用,rownum不是表的属性列,这样写肯定存在问题;再者,rownum随着order或者group子句的不同会不一样,你可以试一下,除了MOD 1,ROWNUM MOD 任何大于1的数都将返回空记录集。
    -----------------------------------------------------------------select A.* from (select rownum rid,table_name.* from table_name where ..........) A,
    (select floor(count(*)/200) as step from (select rownum rid,table_name.* from table_name where .........)) B 
    where mod(A.rid,B.step) = 0这样就可以了吧!!!
      

  22.   

    仅给出一种思路吧
    第一步,先把题目整理下
    题目就是有这样一个源记录集sr
    times                   c1   c2 
    2007-1-30 0:00:01       1.1  2.2  | sr(1)
    2007-1-30 0:05:12       1.4  4.4  | sr(2)
    2007-1-30 0:07:01       2.1  3.2  | sr(3)
    ........
    2007-1-30 0:11:06       1.2  2.3  | sr(n)
    要生成一个从t(0)时间开始,时间间隔为intv,时间点间隔为m的结果记录集dr,也就是:
    times                   c1   c2 
    t(0) + intv * 0         xx   xx  | dr(1)
    t(0) + intv * 1         xx   xx  | dr(2)
    t(0) + intv * 2         xx   xx  | dr(3)
    ........
    t(0) + intv * (m - 1)   xx   xx  | dr(m)
    第二步,构建临时记录集合tr
    为了方便,完全可以假设t(0) < sr(i).times < t(0) + intv * (m - 1)
    并且容易知道sr.times无重复字段,因为一个时间点上不可能有2个值。
    times                   rowid      pre_sr_times       next_sr_times
    t(0)                     null
    ...
    t(0) + intv * (m - 1)    null
    整个临时记录集是由sr记录集合和dr记录集合按照一定的规则合并而成
    规则如下:
    1、将sr记录插入tr,使得tr.times=sr.times tr.rowid=sr.rowid,其他字段全部为空
    2、将dr记录集(此时只有dr.times字段有值)插入tr,
       使得tr.times=t(0) ... t(0)+intv*(m-1),其他字段全部为空
    3、tr集合中的记录是按照tr.times字段升序排列的
    做完后,tr中所有来自sr集合的记录tr.rowid不为空,来自dr集合的记录tr.rowid为空
    第三步,加工tr集合,填充pre_sr_times,next_sr_times
    首先填充pre_sr_times,填充步骤如下:
    第一步,找出所有这样的tr(i)[i>1],tr(i)满足(tr(i).rowid=null)&&(tr(i-1).rowid!=null);
            将tr(i).pre_sr_times=tr(i-1).times
            也就是将所有前置记录来自sr的,并且本身记录来自dr的记录的pre_sr_times
            填充上前置记录的times
    第二步,找出所有这样的tr(i),满足(tr(i).rowid=null)&&(tr(i).pre_sr_times=null);
            将tr(i).pre_sr_times=tr(i-1).pre_sr_times
            将所以来自dr的,pre_sr_times字段尚未填充记录的记录
            填充上其前置记录的pre_sr_times
    然后仿pre_sr_times的步骤填充上next_sr_times
    第四步,填充目的结果集合
    从tr中取出所有的rowid=null的记录,对于这样的记录tr(i) 1<=i<=m
    当tr(i).pre_sr_times - tr(i).times >= tr(i).next_sr_times - tr(i).times时
    tr(i).next_sr_times有效,从sr集合中取出时间为tr(i).next_sr_times的记录填充到dr
    当tr(i).pre_sr_times - tr(i).times < tr(i).next_sr_times - tr(i).times时
    tr(i).pre_sr_times有效,从sr集合中取出时间为tr(i).pre_sr_times的记录填充到dr
    第五步,打完全套,收工了,哈哈
      

  23.   

    select trunc(times,'dd')+a1 times,sum(c1)/count(a1) c1,sum(c2)/count(a1) c2 from
    (select times,c1,c2,a1 from ttt a,
    (select (rownum - 1) /200 a1, rownum /200 a2 from ttt where rownum < 201) b
    where times - trunc(times) between a1 and a2)
    group by a1,trunc(times,'dd')
    条件自己加