具体的sql就不写了, 太长了,需求是这样的:
  
  一个历史表  里面几个关键的字段   一个主键id 公司标识copmanyid   一个成功或失败状态 status  一个createtime    需求很简单   现在要查询下面的数据:
  1  如果 某公司只有一条历史记录,则显示状态为失败的、
  2  如果 公司有多条记录,只要有一条是成功的就不显示,如果都为失败的,则显示最新及最近的一条
我的思路是这样的   在java程序中作判断  然后拼接sql,  多条记录union 一条记录,一条记录的好搞,主要是多条记录的,首先查出多条记录并且全部为失败的公司标识,然后没查出一个公司标识就union一次,  结果表里数据很多,union了几十次,直接卡死,
哪位大侠给个指点 ,实在想不出好的方法了,在sql优化或者在java程序中处理都可以!!!!分不多了,全部献上...

解决方案 »

  1.   


    --此处假设status为0是失败,1成功
    select companyid,max(createtime) d
    from 你的表
    group by companyid
    having (count(1)>1 and count(decode(status,0,null,1))=0)
    or (count(1)=1);
      

  2.   

    是要一次性,所有公司都查出来,还是一个公司 一个公司的查?如果是所有公司都查出来,建议走后台 存储过程。把所有逻辑写到后台PRC里,计算出来后,前台JAVA只管查结果表就好了。
      

  3.   

    上个查询作为子查询,然后按companyid和createtime关联到你的表就可以取出所有字段了
      

  4.   

    这个可以直接写一个存储过程来解决,
    create or replace procedure proc_history
    h_id in number,--输入某公司的ID
    is
    h_countid integer;
    h_countstate integer;
    begin
    select count(*) into h_countid from Table_history where id=h_id;
    if h_countid=1 then
    select * from Table_history where status=0 and id=h_id;--显示状态为失败(0)的数据
    end if;select count(*) into h_countstate from Table_history where status=1;
    if h_countstate=0 then
    select * from (select * from Table_history order by createtime desc) where rownum=1
    end if;
    end;
      

  5.   


    -- 0:success 1:failed
    WITH tb AS (
         SELECT 1 tid,'c1' copmanyid,0 status,TO_DATE('2011-04-01 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 2 tid,'c2' copmanyid,1 status,TO_DATE('2011-04-02 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 3 tid,'c3' copmanyid,1 status,TO_DATE('2011-04-03 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 4 tid,'c3' copmanyid,0 status,TO_DATE('2011-04-04 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 5 tid,'c3' copmanyid,1 status,TO_DATE('2011-04-05 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 6 tid,'c4' copmanyid,1 status,TO_DATE('2011-04-08 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 7 tid,'c4' copmanyid,1 status,TO_DATE('2011-04-07 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL UNION ALL
         SELECT 8 tid,'c4' copmanyid,1 status,TO_DATE('2011-04-09 15:10:42','yyyy-mm-dd hh24:mi:ss') createtime FROM DUAL
    )
    SELECT n.tid,
           n.copmanyid,
           n.status,
           n.createtime
      FROM (SELECT m.tid,
                   m.copmanyid,
                   m.status,
                   m.createtime,
                   ROW_NUMBER() OVER(PARTITION BY m.copmanyid ORDER BY m.createtime DESC, m.tid ASC) rn
              FROM (SELECT t.*,
                           COUNT(*) OVER(PARTITION BY t.copmanyid) total_cnt,
                           SUM(DECODE(t.status, 0, 1, 0)) OVER(PARTITION BY t.copmanyid) success_total_cnt
                      FROM tb t) m
             WHERE (m.total_cnt = 1 AND m.status = 1)
                OR (m.total_cnt > 1 AND m.success_total_cnt = 0)) n
     WHERE n.rn <= 2;       TID COPMANYID     STATUS CREATETIME
    ---------- --------- ---------- -----------
             2 c2                 1 2011/04/02
             8 c4                 1 2011/04/09
             6 c4                 1 2011/04/08
      

  6.   

    select * from 你的表
    where (companyid,createtime)=(select companyid,max(createtime) d
        from 你的表
        group by companyid
        having ((count(1)>1 and count(decode(status,0,null,1))=0)
            or (count(1)=1)));
      

  7.   


    执行了下    [Error Code: 1427, SQL State: 21000]  ORA-01427: 单行子查询返回多个行
      

  8.   


    --你不會同個companyid會有重復的createtime吧,那很無語,呵呵
    select 你的表.* 
    from 你的表,(
    select companyid,max(createtime) d
    from 你的表
    group by companyid
    having (count(1)>1 and count(decode(status,0,null,1))=0)
    or (count(1)=1))t1
    where 你的表.companyid=t1.companyid and 你的表.createtime=t1.d;
      

  9.   

    分析函数 同学,oracle赋予了你力量,利用10楼同学的sql,修改一了一下。SELECT N.TID, N.COPMANYID, N.STATUS, N.CREATETIME
      FROM (SELECT T.*,
                   --根据COPMANYID分组求记录条数,为了满足你[某公司只有一条或多条历史记录 的判断]
                   COUNT(*) OVER(PARTITION BY T.COPMANYID) TOTAL_CNT,
                   --根据COPMANYID分组求成功的次数,10楼同学此处认为0为成功,1为失败
                   SUM(DECODE(T.STATUS, 0, 1, 0)) OVER(PARTITION BY T.COPMANYID) SUCCESS_TOTAL_CNT,
                   --根据COPMANYID分组,按照createtime降序,TID升序排序,为了满足你[显示最新及最近的一条 的判断]
                   ROW_NUMBER() OVER(PARTITION BY T.COPMANYID ORDER BY T.CREATETIME DESC, T.TID ASC) RN
              FROM TB T) N
     WHERE (N.TOTAL_CNT = 1 AND N.STATUS = 1) --只有一条记录,显示成功的
        OR (N.TOTAL_CNT > 1 AND N.SUCCESS_TOTAL_CNT = 0 AND N.RN <= 1); --多条记录显示没有成功的第一条记录
      

  10.   

    我感觉没有这么麻烦吧,先查出数据库所以有成功记录的单位(dws),然后另一个sql里的where条件有一个是 单位 not in (dws) ,之后过滤出来的就是全部没有成功的单位,之后  select 单位名称, max(createtime ) from tablename t   group by 单位名称。我试过了,可以实现。
      

  11.   


    select 单位名称, max(createtime ) from tablename t group by 单位名称  这样不能去第一条  因为时间   返回的是多条记录    哎  纠结