表Aid Number Re
1 111 aaa
2 222 bbb
3 444 ccc
4 333 ddd
5 555 eee
-----------------------------------
表Bid Number dongzuo time
1 111 one 2008-8-1 13:00:00
2 111 two 2008-8-1 14:00:00
3 111 two 2008-8-2 15:00:00
4 111 two 2008-8-3 13:00:005 222 one 2008-8-1 13:30:00
6 222 two 2008-8-1 14:00:007 333 two 2008-8-1 13:13:00
8 333 one 2008-8-1 13:30:00
9 333 two 2008-8-2 11:00:00
10 333 two 2008-8-3 15:00:0011 444 two 2008-8-1 12:00:00
12 444 one 2008-8-2 13:00:0013 555 two 2008-8-2 13:00:00
-----------------------------------------------
我需要得到一个结果集,得到每一个号码在one动作后面的第一个和最后一个two动作,如果只有一个two动作,作为第一个,如果没有one动作,那么什么都不显示。而且要竖表转横表,结果如下:Number Re one one_time first_two first_two_time last_two last_two_time
111 aaa one 2008-8-1 13:00:00 two 2008-8-1 14:00:00 two 2008-8-3 13:00:00
222 bbb one 2008-8-1 13:30:00 two 2008-8-1 14:00:00
333 ddd one 2008-8-1 13:30:00 two 2008-8-2 11:00:00 two 2008-8-3 15:00:00
444 ccc one 2008-8-2 13:00:00
555 eee 111--中间的那个2008-8-2 15:00:00不显示
222--one之后只有一个two,作为第一个two
333--one之前的那个two不要
444--one之前的那个two不要
555--没有one,什么都不显示
1 111 aaa
2 222 bbb
3 444 ccc
4 333 ddd
5 555 eee
-----------------------------------
表Bid Number dongzuo time
1 111 one 2008-8-1 13:00:00
2 111 two 2008-8-1 14:00:00
3 111 two 2008-8-2 15:00:00
4 111 two 2008-8-3 13:00:005 222 one 2008-8-1 13:30:00
6 222 two 2008-8-1 14:00:007 333 two 2008-8-1 13:13:00
8 333 one 2008-8-1 13:30:00
9 333 two 2008-8-2 11:00:00
10 333 two 2008-8-3 15:00:0011 444 two 2008-8-1 12:00:00
12 444 one 2008-8-2 13:00:0013 555 two 2008-8-2 13:00:00
-----------------------------------------------
我需要得到一个结果集,得到每一个号码在one动作后面的第一个和最后一个two动作,如果只有一个two动作,作为第一个,如果没有one动作,那么什么都不显示。而且要竖表转横表,结果如下:Number Re one one_time first_two first_two_time last_two last_two_time
111 aaa one 2008-8-1 13:00:00 two 2008-8-1 14:00:00 two 2008-8-3 13:00:00
222 bbb one 2008-8-1 13:30:00 two 2008-8-1 14:00:00
333 ddd one 2008-8-1 13:30:00 two 2008-8-2 11:00:00 two 2008-8-3 15:00:00
444 ccc one 2008-8-2 13:00:00
555 eee 111--中间的那个2008-8-2 15:00:00不显示
222--one之后只有一个two,作为第一个two
333--one之前的那个two不要
444--one之前的那个two不要
555--没有one,什么都不显示
解决方案 »
- 100分在线等:SQL Developer转移SQL Server Express问题求助
- 如何在一个数据库实例中调用另一个数据库实例里的自定义函数
- 求教两个问题。
- 请高手提供一个具体的oracle触发器例子
- 两表连接查询的问题应该很简单
- 统计问题的sql,辛苦赐教
- 同样的查询语句在SQLserver下是好用的,可是在oracle下执行出错,望解答
- oracle 11g快捷版用来学习够吗?
- 想深入沟通Oracle技术吗?请大家到这里(Oracle技术论坛www.oraclebbs.com)来一起讨论!
- oracle 中,BITMAP索引为什么会导致INSERT的性能严重下降呢????
- 求一个较难的SQL的写法(线段组成链路)
- 索引使用问题
然后用DECODE生成行列转换表,再和A表关联
WITH a AS
(SELECT 1 ID, 111 "number", 'aaa' re
FROM DUAL
UNION ALL
SELECT 2, 222, 'bbb'
FROM DUAL
UNION ALL
SELECT 3, 444, 'ccc'
FROM DUAL
UNION ALL
SELECT 4, 333, 'ddd'
FROM DUAL
UNION ALL
SELECT 5, 555, 'eee'
FROM DUAL),
b AS
(SELECT 1 ID, 111 "number", 'one' dongzuo,
TO_DATE ('2008-8-1 13:00:00', 'yyyy-mm-dd hh24:mi:ss') TIME
FROM DUAL
UNION ALL
SELECT 2, 111, 'two' dongzuo,
TO_DATE ('2008-8-1 14:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 3, 111, 'two' dongzuo,
TO_DATE ('2008-8-2 15:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 4, 111, 'two' dongzuo,
TO_DATE ('2008-8-3 13:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 5, 222, 'one' dongzuo,
TO_DATE ('2008-8-1 13:30:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 6, 222, 'two' dongzuo,
TO_DATE ('2008-8-1 14:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 7, 333, 'two' dongzuo,
TO_DATE ('2008-8-1 13:13:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 8, 333, 'one' dongzuo,
TO_DATE ('2008-8-1 13:30:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 9, 333, 'two' dongzuo,
TO_DATE ('2008-8-2 11:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 10, 333, 'two' dongzuo,
TO_DATE ('2008-8-3 15:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 11, 444, 'two' dongzuo,
TO_DATE ('2008-8-1 12:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 12, 444, 'one' dongzuo,
TO_DATE (' 2008-8-2 13:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL
UNION ALL
SELECT 13, 555, 'two' dongzuo,
TO_DATE (' 2008-8-2 13:00:00', 'yyyy-mm-dd hh24:mi:ss')
FROM DUAL)
SELECT a."number", a.re, bbb.one, bbb.one_time, bbb.first_two,
bbb.first_two_time, bbb.last_two, bbb.last_two_time
FROM a,
(SELECT bb."number" num,
MAX (DECODE (bb.dongzuo, 'one', bb.dongzuo, NULL)) one,
MAX (DECODE (bb.dongzuo,
'one', TO_CHAR (bb.TIME,
'yyyy-mm-dd hh24:mi:ss'
),
NULL
)
) one_time,
MAX (DECODE (bb.o_t,
1, NULL,
DECODE (bb.dongzuo, 'two', bb.dongzuo, NULL)
)
) first_two,
MAX
(DECODE
(bb.o_t,
1, NULL,
DECODE (bb.dongzuo,
'two', DECODE
(bb.f_num,
1, TO_CHAR
(bb.TIME,
'yyyy-mm-dd hh24:mi:ss'
),
NULL
),
NULL
)
)
) first_two_time,
MAX (DECODE (bb.o_t,
1, NULL,
DECODE (bb.dongzuo,
'two', DECODE (bb.l_num,
1, DECODE (bb.f_num,
1, NULL,
bb.dongzuo
),
NULL
)
)
)
) last_two,
MAX
(DECODE
(bb.o_t,
1, NULL,
DECODE
(bb.dongzuo,
'two', DECODE
(bb.l_num,
1, DECODE
(bb.f_num,
1, NULL,
TO_CHAR (bb.TIME,
'yyyy-mm-dd hh24:mi:ss'
)
),
NULL
)
)
)
) last_two_time
FROM (SELECT b.*,
ROW_NUMBER () OVER (PARTITION BY b."number", b.dongzuo ORDER BY TIME)
f_num,
ROW_NUMBER () OVER (PARTITION BY b."number", b.dongzuo ORDER BY TIME DESC)
l_num,
ROW_NUMBER () OVER (PARTITION BY b."number" ORDER BY b.dongzuo)
o_t
FROM b) bb
GROUP BY bb."number") bbb
WHERE a."number" = bbb.num(+)
ORDER BY 1结果
Row# number REMARK ONE ONE_TIME FIRST_TWO FIRST_TWO_TIME LAST_TWO LAST_TWO_TIME1 111 aaa one 2008-08-01 13:00:00 two 2008-08-01 14:00:00 two 2008-08-03 13:00:00
2 222 bbb one 2008-08-01 13:30:00 two 2008-08-01 14:00:00
3 333 ddd one 2008-08-01 13:30:00 two 2008-08-01 13:13:00 two 2008-08-03 15:00:00
4 444 ccc one 2008-08-02 13:00:00 two 2008-08-01 12:00:00
5 555 eee
a.Number,a.re,t.first_one_time,t.first_tow_time,decode(t.first_tow_time,t.last_tow_time,'',t.last_tow_time) as last_tow_time
from
(
SELECT b.Number,b.dongzuo,
FIRST_VALUE (b.time) over ( partition by b.Number order by b.dongzuo,b.time ) as first_one_time,
FIRST_VALUE (b.time) over ( partition by b.Number order by b.dongzuo desc,b.time ) as first_tow_time,
FIRST_VALUE (b.time) over ( partition by b.Number order by b.dongzuo desc,b.time desc ) as last_tow_time,
row_number() over ( partition by b.Number,b.dongzuo order by rownum ) as rm
from 表B b
) t,表A a
where t.rm(+) = 1 and t.dongzuo(+) = 'one'
and a.Number =t.Number(+)
bbb.first_two_time, bbb.last_two, bbb.last_two_time
FROM a,
(SELECT bb."number" num,
MAX (DECODE (bb.dongzuo, 'one', bb.dongzuo, NULL)) one,
MAX (DECODE (bb.dongzuo,
'one', TO_CHAR (bb.TIME,
'yyyy-mm-dd hh24:mi:ss'
),
NULL
)
) one_time,
MAX (DECODE (bb.o_t,
1, NULL,
DECODE (bb.dongzuo, 'two', bb.dongzuo, NULL)
)
) first_two,
MAX
(DECODE
(bb.o_t,
1, NULL,
DECODE (bb.dongzuo,
'two', DECODE
(bb.f_num,
1, TO_CHAR
(bb.TIME,
'yyyy-mm-dd hh24:mi:ss'
),
NULL
),
NULL
)
)
) first_two_time,
MAX (DECODE (bb.o_t,
1, NULL,
DECODE (bb.dongzuo,
'two', DECODE (bb.l_num,
1, DECODE (bb.f_num,
1, NULL,
bb.dongzuo
),
NULL
)
)
)
) last_two,
MAX
(DECODE
(bb.o_t,
1, NULL,
DECODE
(bb.dongzuo,
'two', DECODE
(bb.l_num,
1, DECODE
(bb.f_num,
1, NULL,
TO_CHAR (bb.TIME,
'yyyy-mm-dd hh24:mi:ss'
)
),
NULL
)
)
)
) last_two_time
FROM (SELECT b.*,
ROW_NUMBER () OVER (PARTITION BY b."number", b.dongzuo ORDER BY TIME)
f_num,
ROW_NUMBER () OVER (PARTITION BY b."number", b.dongzuo ORDER BY TIME DESC)
l_num,
ROW_NUMBER () OVER (PARTITION BY b."number" ORDER BY TIME,
b.dongzuo) o_t
FROM (SELECT c.*,
ROW_NUMBER () OVER (PARTITION BY c."number" ORDER BY TIME,
c.dongzuo) o_t_1
FROM b c) b
WHERE dongzuo || o_t_1 <> 'two1') bb
GROUP BY bb."number") bbb
WHERE a."number" = bbb.num(+)
ORDER BY 1
结果
Row# number REMARK ONE ONE_TIME FIRST_TWO FIRST_TWO_TIME LAST_TWO LAST_TWO_TIME1 111 aaa one 2008-08-01 13:00:00 two 2008-08-01 14:00:00 two 2008-08-03 13:00:00
2 222 bbb one 2008-08-01 13:30:00 two 2008-08-01 14:00:00
3 333 ddd one 2008-08-01 13:30:00 two 2008-08-02 11:00:00 two 2008-08-03 15:00:00
4 444 ccc one 2008-08-02 13:00:00
5 555 eee
SELECT
a.Number,a.re,t.first_one_time,t.first_tow_time,decode(t.first_tow_time,t.last_tow_time,'',t.last_tow_time) as last_tow_time
from
(
SELECT b.Number,b.dongzuo,
FIRST_VALUE (b.time) over ( partition by b.Number order by b.dongzuo,b.time ) as first_one_time,
FIRST_VALUE (decode(b.dongzuo,'two',b.time,'')) over ( partition by b.Number order by b.dongzuo desc,b.time ) as first_tow_time,
FIRST_VALUE (decode(b.dongzuo,'two',b.time,'')) over ( partition by b.Number order by b.dongzuo desc,b.time desc ) as last_tow_time,
row_number() over ( partition by b.Number,b.dongzuo order by rownum ) as rm
from 表B b
) t,表A a
where t.rm(+) = 1 and t.dongzuo(+) = 'one'
and a.Number =t.Number(+)
我用你的语句的测试结果
Row# Number REMARK FIRST_ONE_TIME FIRST_TOW_TIME LAST_TOW_TIME1 111 aaa 2008/8/1 13:00:00 2008/8/1 14:00:00 03-AUG-08
2 222 bbb 2008/8/1 13:30:00 2008/8/1 14:00:00
3 333 ddd 2008/8/1 13:30:00 2008/8/1 13:13:00 03-AUG-08
4 444 ccc 2008/8/2 13:00:00 2008/8/1 12:00:00
5 555 eee 还需要修正
写语句的时候很麻烦,我上面全是用""的
SQL> SELECT * FROM AAA; SID NUM REMARK
---------- ---------- ----------
1 111 AAA
2 222 BBB
3 333 CCC
4 444 DDD
5 555 EEESQL> SELECT * FROM BBB; SID NUM ACTION STIME
---------- ---------- ---------- -----------
1 111 ONE 8/1/2008 1:
2 111 TWO 8/1/2008 2:
3 111 TWO 8/2/2008 3:
4 111 TWO 8/3/2008 1:
5 222 ONE 8/1/2008 1:
6 222 TWO 8/1/2008 2:
7 333 TWO 8/1/2008 1:
8 333 ONE 8/1/2008 1:
9 333 TWO 8/2/2008 11
10 333 TWO 8/3/2008 3:
11 444 TWO 8/1/2008 12
12 444 ONE 8/2/2008 1:
13 555 TWO 8/2/2008 1:13 rows selected
SQL> SELECT A.NUM,
2 A.REMARK,
3 C.ONE,
4 C.ONE_TIME,
5 DECODE(C.ONE,NULL,NULL,DECODE(SIGN(C.FIRST_TWO_TIME-C.ONE_TIME),-1,NULL,C.FIRST_TWO)) "FIRST_TWO",
6 DECODE(C.ONE,NULL,NULL,DECODE(SIGN(C.FIRST_TWO_TIME-C.ONE_TIME),-1,NULL,C.FIRST_TWO_TIME)) "FIRST_TWO_TIME",
7 DECODE(C.ONE,NULL,NULL,DECODE(C.FIRST_TWO_TIME,C.LAST_TWO_TIME,NULL,C.LAST_TWO)) "LAST_TWO",
8 DECODE(C.ONE,NULL,NULL,DECODE(C.FIRST_TWO_TIME,C.LAST_TWO_TIME,NULL,C.LAST_TWO_TIME)) "LAST_TWO_TIME"
9 FROM AAA A,
10 (
11 SELECT B.NUM,
12 MIN(DECODE(UPPER(ACTION),'ONE','ONE',NULL)) "ONE",
13 MIN(DECODE(UPPER(ACTION),'ONE',STIME,NULL)) "ONE_TIME",
14 MIN(DECODE(UPPER(ACTION),'TWO','TWO',NULL)) "FIRST_TWO",
15 MIN(DECODE(UPPER(ACTION),'TWO',STIME,NULL)) "FIRST_TWO_TIME",
16 MAX(DECODE(UPPER(ACTION),'TWO','TWO',NULL)) "LAST_TWO",
17 MAX(DECODE(UPPER(ACTION),'TWO',STIME,NULL)) "LAST_TWO_TIME"
18 FROM BBB B
19 WHERE NOT EXISTS (
20 SELECT 1
21 FROM BBB BB
22 WHERE B.NUM = BB.NUM
23 AND UPPER(BB.ACTION) = 'ONE'
24 AND B.STIME < BB.STIME
25 )
26 GROUP BY B.NUM
27 )C
28 WHERE A.NUM = C.NUM(+); NUM REMARK ONE C.ONE_TIME FIRST_TWO FIRST_TWO_TIME LAST_TWO LAST_TWO_TIME
---------- ---------- --- ------------------------------ --------- ------------------- -------- -------------------
111 AAA ONE 2008-08-01 13:00:00 TWO 2008-08-01 14:00:00 TWO 2008-08-03 13:00:00
222 BBB ONE 2008-08-01 13:30:00 TWO 2008-08-01 14:00:00
333 CCC ONE 2008-08-01 13:30:00 TWO 2008-08-02 11:00:00 TWO 2008-08-03 15:00:00
444 DDD ONE 2008-08-02 13:00:00
555 EEE SQL>
SELECT A.NUM,
A.REMARK,
C.ONE,
C.ONE_TIME,
DECODE(C.ONE,NULL,NULL,DECODE(SIGN(C.FIRST_TWO_TIME-C.ONE_TIME),-1,NULL,C.FIRST_TWO)) "FIRST_TWO",
DECODE(C.ONE,NULL,NULL,DECODE(SIGN(C.FIRST_TWO_TIME-C.ONE_TIME),-1,NULL,C.FIRST_TWO_TIME)) "FIRST_TWO_TIME",
DECODE(C.ONE,NULL,NULL,DECODE(C.FIRST_TWO_TIME,C.LAST_TWO_TIME,NULL,C.LAST_TWO)) "LAST_TWO",
DECODE(C.ONE,NULL,NULL,DECODE(C.FIRST_TWO_TIME,C.LAST_TWO_TIME,NULL,C.LAST_TWO_TIME)) "LAST_TWO_TIME"
FROM AAA A,
(
SELECT B.NUM,
MIN(DECODE(ACTION,'one','one',NULL)) "ONE",
MIN(DECODE(ACTION,'one',STIME,NULL)) "ONE_TIME",
MIN(DECODE(ACTION,'two','two',NULL)) "FIRST_TWO",
MIN(DECODE(ACTION,'two',STIME,NULL)) "FIRST_TWO_TIME",
MAX(DECODE(ACTION,'two','two',NULL)) "LAST_TWO",
MAX(DECODE(ACTION,'two',STIME,NULL)) "LAST_TWO_TIME"
FROM BBB B
WHERE NOT EXISTS (
SELECT 1
FROM BBB BB
WHERE B.NUM = BB.NUM
AND BB.ACTION = 'one'
AND B.STIME < BB.STIME
)
GROUP BY B.NUM
)C
WHERE A.NUM = C.NUM(+);
Try it ..