[英]Calculated column value based on rows above SQL
我在我们的程序数据库中有这个愚蠢的表。 程序不是我们的,因此无法更改表格内容。 该表以不可读的代码存储类似 SQL 的表达式。 我正在将这些值转换回 SQL 表达式以运行这些表达式。 到目前为止,翻译部分进行得很顺利。 到目前为止的结果是一个如下表:
+--------+--------+---------+----------------+-----------------+
| CODE | SEQNUM | LOGICAL | EXPRESSION | EXPRESSIONVALUE |
+--------+--------+---------+----------------+-----------------+
| A23000 | 1 | NULL | OTHERCODE LIKE | 'A522%' |
+--------+--------+---------+----------------+-----------------+
| A23000 | 2 | OR | OTHERCODE = | 'A62342' |
+--------+--------+---------+----------------+-----------------+
| A23000 | 3 | OR | OTHERCODE = | 'A62343' |
+--------+--------+---------+----------------+-----------------+
| B43000 | 1 | NULL | OTHERCODE IN | 'B34324' |
+--------+--------+---------+----------------+-----------------+
| B43000 | 2 | NULL | NULL | 'B92338' |
+--------+--------+---------+----------------+-----------------+
| B43000 | 3 | NULL | NULL | 'B92342' |
+--------+--------+---------+----------------+-----------------+
| B43000 | 4 | NULL | NULL | 'B02349' |
+--------+--------+---------+----------------+-----------------+
| B43000 | 5 | OR | OTHERCODE = | 'B32443' |
+--------+--------+---------+----------------+-----------------+
或者为了让我拥有有效的 SQL 语句,我需要在有“in-expression”的行后面加上逗号。 我认为这需要基于较早的行。 我需要有一张像:
+--------+--------+---------+----------------+-----------------+------------+
| CODE | SEQNUM | LOGICAL | EXPRESSION | EXPRESSIONVALUE | CALCULETED |
+--------+--------+---------+----------------+-----------------+------------+
| A23000 | 1 | NULL | OTHERCODE LIKE | 'A522%' | NULL |
+--------+--------+---------+----------------+-----------------+------------+
| A23000 | 2 | OR | OTHERCODE = | 'A62342' | NULL |
+--------+--------+---------+----------------+-----------------+------------+
| A23000 | 3 | OR | OTHERCODE = | 'A62343' | NULL |
+--------+--------+---------+----------------+-----------------+------------+
| B43000 | 1 | NULL | OTHERCODE IN | 'B34324' | ',' |
+--------+--------+---------+----------------+-----------------+------------+
| B43000 | 2 | NULL | NULL | 'B92338' | ',' |
+--------+--------+---------+----------------+-----------------+------------+
| B43000 | 3 | NULL | NULL | 'B92342' | ',' |
+--------+--------+---------+----------------+-----------------+------------+
| B43000 | 4 | NULL | NULL | 'B02349' | NULL |
+--------+--------+---------+----------------+-----------------+------------+
| B43000 | 5 | OR | OTHERCODE = | 'B32443' | NULL |
+--------+--------+---------+----------------+-----------------+------------+
这可能与SQL有关吗?
这会有帮助吗?
SQL> with test (code, seqnum, logical, expression, value) as
2 (select 'a23', 1, null, 'othercode like', 'a522%' from dual union all
3 select 'a23', 2, 'or', 'othercode =' , 'a62342' from dual union all
4 select 'a23', 3, 'or', 'othercode =' , 'a62343' from dual union all
5 --
6 select 'b43', 1, null, 'othercode in' , 'b34324' from dual union all
7 select 'b43', 2, null, 'null' , 'b92342' from dual union all
8 select 'b43', 3, null, 'null' , 'b02349' from dual union all
9 select 'b43', 4, 'or', 'othercode =' , 'b34243' from dual
10 ),
11 poc as
12 -- SEQNUM where "IN" begins
13 (select code, min(seqnum) minseq
14 from test
15 where expression = 'othercode in'
16 group by code
17 ),
18 zav as
19 -- SEQNUM where "IN" part ends
20 (select t.code, max(t.seqnum) maxseq
21 from test t join poc p on p.code = t.code
22 where t.seqnum > p.minseq
23 and t.expression <> 'null'
24 group by t.code
25 )
26 select t.code, t.seqnum, t.logical, t.expression, t.value,
27 case when t.seqnum >= p.minseq and t.seqnum < z.maxseq then ','
28 else null
29 end calc
30 from test t left join poc p on p.code = t.code
31 left join zav z on z.code = t.code
32 order by code, seqnum;
COD SEQNUM LO EXPRESSION VALUE C
--- ---------- -- -------------- ------- -
a23 1 othercode like a522%
a23 2 or othercode = a62342
a23 3 or othercode = a62343
b43 1 othercode in b34324 ,
b43 2 null b92342 ,
b43 3 null b02349 ,
b43 4 or othercode = b342443
7 rows selected.
SQL>
您可以使用分析函数执行此逻辑:
select t.*,
(case when coalesce(expression, lag(expression ignore nulls) over (partition by code order by seqnum)) like '% in' and
((lead(logical) over (partition by code order by seqnum) is null and
lead(seqnum) over (partition by code order by seqnum) is not null
) or
lead(seqnum) over (partition by code order by seqnum) is not null
)
then ','
end) as calculated
from test t;
的逻辑来实现识别具有相关联的行in
的逻辑-这是lag(ignore nulls)
。
除了最后一行之外,所有这些行都有一个逗号。 这很棘手,因为最后一行可能是表达式的结尾( code
的最后一行seqnum
)。 或者,可能会出现一个新的布尔表达式。
我添加了更多测试用例来证明这是有效的:
in
之后没有表达式。in
列表中只有一个值。in
之前的另一个表达式。这是db<>小提琴。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.