具体的sql就不写了, 太长了,需求是这样的:
一个历史表 里面几个关键的字段 一个主键id 公司标识copmanyid 一个成功或失败状态 status 一个createtime 需求很简单 现在要查询下面的数据:
1 如果 某公司只有一条历史记录,则显示状态为失败的、
2 如果 公司有多条记录,只要有一条是成功的就不显示,如果都为失败的,则显示最新及最近的一条
我的思路是这样的 在java程序中作判断 然后拼接sql, 多条记录union 一条记录,一条记录的好搞,主要是多条记录的,首先查出多条记录并且全部为失败的公司标识,然后没查出一个公司标识就union一次, 结果表里数据很多,union了几十次,直接卡死,
哪位大侠给个指点 ,实在想不出好的方法了,在sql优化或者在java程序中处理都可以!!!!分不多了,全部献上...
一个历史表 里面几个关键的字段 一个主键id 公司标识copmanyid 一个成功或失败状态 status 一个createtime 需求很简单 现在要查询下面的数据:
1 如果 某公司只有一条历史记录,则显示状态为失败的、
2 如果 公司有多条记录,只要有一条是成功的就不显示,如果都为失败的,则显示最新及最近的一条
我的思路是这样的 在java程序中作判断 然后拼接sql, 多条记录union 一条记录,一条记录的好搞,主要是多条记录的,首先查出多条记录并且全部为失败的公司标识,然后没查出一个公司标识就union一次, 结果表里数据很多,union了几十次,直接卡死,
哪位大侠给个指点 ,实在想不出好的方法了,在sql优化或者在java程序中处理都可以!!!!分不多了,全部献上...
解决方案 »
- dg 实验的问题
- Ref Cursor
- 高手指点:安装oracle8
- 急,ORACLE分组查询
- 在存储过程中用一个变量存储where语句(AA),这个变量如何与select * from 表1 ||AA
- 请问哪里有关于oracle存储过程的资料下载?
- 挑战的方案
- 请各位帮忙解决:如何在oracle 8.1.7客户端上用exp.exe备份oracle 8.0.5服务端的数据?
- [求助] ORA-04031: unable to allocate 4200 bytes of shared memory
- <><><><><><><><><><><>vc++与oracal的问题!!!<><><><><><><><><><><><><>
- 求助 oracle用户对表的操作权限问题
- oracle中自增长的问题
--此处假设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);
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;
-- 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
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)));
执行了下 [Error Code: 1427, SQL State: 21000] ORA-01427: 单行子查询返回多个行
--你不會同個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;
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); --多条记录显示没有成功的第一条记录
select 单位名称, max(createtime ) from tablename t group by 单位名称 这样不能去第一条 因为时间 返回的是多条记录 哎 纠结