我有一个表,表示从特定文本文件格式读取的数据的逐行转储。每行代表“主”或“详细”行,通过rec_type
代码表示。我想写一个查询,在相关的细节线旁边获取“主”线。我想出了一些可以胜任这项工作的东西,但它看起来有些过时,并且对更好的方法感兴趣。
CREATE TABLE mdtest
(rec_seq NUMBER PRIMARY KEY
,rec_type VARCHAR2(3) NOT NULL
,rec_data VARCHAR2(100) NOT NULL);
INSERT INTO mdtest VALUES (1, '100', 'Bill Jones');
INSERT INTO mdtest VALUES (2, '200', '20080115,100.25');
INSERT INTO mdtest VALUES (3, '100', 'John Smith');
INSERT INTO mdtest VALUES (4, '200', '20090701,80.95');
INSERT INTO mdtest VALUES (5, '200', '20091231,110.35');
期望的结果:
SEQ_EMP EMP_NAME SEQ_DATA EMP_DATA
======= ========== ======== ===============
1 Bill Jones 2 20080115,100.25
3 John Smith 4 20090701,80.95
3 John Smith 5 20091231,110.35
假设:
100
”100
”记录在200
”记录
注意:这适用于Oracle 9i,但我们今年应该升级到11g R1。
答案 0 :(得分:2)
这是我到目前为止所拥有的:
SELECT seq_emp
,SUBSTR(emp_seq_name,10) emp_name
,seq_data
,emp_data
FROM (SELECT MAX(CASE WHEN rec_type = '100' THEN rec_seq END)
OVER (ORDER BY rec_seq
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) seq_emp
,MAX(CASE
WHEN rec_type = '100'
THEN TO_CHAR(rec_seq,'fm00000000') || '|' || rec_data
END)
OVER (ORDER BY rec_seq
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) emp_seq_name
,rec_seq seq_data
,rec_type
,rec_data emp_data
FROM mdtest)
WHERE rec_type = '200'
ORDER BY seq_data;
正如您所看到的,我正在使用MAX报告分析功能,其窗口从设置的顶部开始到当前行,以获得当前“200”记录的相关“100”记录;然后在外部查询中我丢弃了不需要的“100”记录。
要获取emp_name,我必须在rec_seq中附加数据,以便MAX函数仍然选择正确的头记录;然后在外部查询中,我关闭了rec_seq。
我使用过其他分析函数和语法,包括FIRST_VALUE和KEEP语法,但这些似乎都不能使这项工作更简单;困难在于窗口是由rec_type的值定义的,而不是一些常量偏移。
答案 1 :(得分:1)
为了简化,您认为在处理之前将每种记录类型加载到单独的导入表中是否值得?
create table mdtest100 as select * from mdtest where rec_type = 100;
create table mdtest200 as select * from mdtest where rec_type = 200;
with mdtest_detail as
(
select
(select max(m.rec_seq) from mdtest100 m
where m.rec_seq < r200.rec_seq) master_rec_seq,
r200.*
from
mdtest200 r200
)
select
m.rec_seq seq_emp,
m.rec_data emp_name,
d.rec_seq seq_data,
d.rec_data emp_data
from
mdtest_detail d
inner join mdtest100 m on m.rec_seq = d.master_rec_seq
order by
seq_emp,
seq_data;
SEQ_EMP EMP_NAME SEQ_DATA EMP_DATA
1 Bill Jones 2 20080115,100.25
3 John Smith 4 20090701,80.95
3 John Smith 5 20091231,110.35
这可能会使自己成为一个更易于维护的解决方案,并且可以让您分别解析并验证通信分离的EMP_DATA字段。
只是想一想 - 如果您只是在寻找Google Analytics解决方案,请抱歉。