使用拆分变量输入和内/外括号在Oracle中实现BODMAS表达式求值

rnmwe5a2  于 2023-06-22  发布在  Oracle
关注(0)|答案(1)|浏览(130)

bodmas表达式的Oracle实现,基于给定的表达式拆分为2个变量。
让我们说,我有下面的表达式
((规则1和规则2和规则3)和(不(规则4))
我有一个包含以下记录的表
Item_no item_type active_from active_to rule id 10001 SAR 01-Jan-2023 31-Jan-2023 rule1 10001 SAR 01-Feb-2023 28-Feb-2023 rule1 10001 SAR 01-Jan-2023 31-Dec-9999 rule2 10001 SAR 01-Feb-2023 28-Feb-2023 rule3 10001 SAR 01-Feb-2023年12月31日规则3 10001 SAR 2023年1月1日规则4
这里基于ruleid列,我需要实现bodmass类型评估。
I.e.in 上面的表达式,首先我需要首先评估所有括号中的'and'子句,并获得公共有效期(这里的'and'表示rule 1,rule 2,rule 3之间的所有active from和active to日期的交集),然后基于此输出,我需要使用not in clause(minus)Rule 4。
我尝试使用bodmass动态地基于ruleid列实现对上表中的active from和active to子句的求值。无论我得到什么表达式,我都需要基于bodmas类型评估来评估'active from'和'active to'。请注意,表达式可以是任何类型。(AND,OR,NOT)
我尝试的是:
在这种情况下,我需要用'AND'运算符传递rule 1和rule 2并获得结果,并将结果作为R1。现在我需要用'And'操作符将R1与Rule 3结合起来,得到R2的结果。一旦完成了所有的Rule 1、Rule 2和Rule 3,我需要计算R2,而不是Rule 4。
另一个表达式示例:((规则1和规则2)或(规则3和规则4))
在这种情况下,步骤1:rule 1和rule 2得到的结果与R1 Step2相同:规则3和规则4得到结果R2步骤3:R1或与R2一起得到最终结果。
如何在这个oracle中实现bodmas表达式求值。(首先按照2-2规则评估所有内括号,然后评估外括号)?
计划先创建表并存储内括号结果,然后再存储外括号以供执行,但如果我在www.example.com中有多个规则与同一运算符组合,则会卡住brackets.as我的函数一次只允许2个规则

ve7v8dk2

ve7v8dk21#

修改my answer to your previous question(你可以自己做),然后对于rule1 and rule2 and rule3 and not rule4,你可以用途:

SELECT item_no,
       item_type,
       active_from
       + CASE
         WHEN prev_rule4 > 0
         THEN INTERVAL '1' SECOND
         ELSE INTERVAL '0' SECOND
         END AS active_from,
       active_to
       - CASE
         WHEN next_rule4 > 0
         THEN INTERVAL '1' SECOND
         ELSE INTERVAL '0' SECOND
         END AS active_to
FROM   (
  SELECT item_no,
         item_type,
         rule_id,
         dt,
         COALESCE(
           SUM(CASE rule_id WHEN 'rule1' THEN active END) OVER (
             PARTITION BY item_no, item_type ORDER BY dt, ACTIVE DESC
           ),
           0
         ) AS rule1,
         COALESCE(
           SUM(CASE rule_id WHEN 'rule2' THEN active END) OVER (
             PARTITION BY item_no, item_type ORDER BY dt, ACTIVE DESC
           ),
           0
         ) AS rule2,
         COALESCE(
           SUM(CASE rule_id WHEN 'rule3' THEN active END) OVER (
             PARTITION BY item_no, item_type ORDER BY dt, ACTIVE DESC
           ),
           0
         ) AS rule3,
         COALESCE(
           SUM(CASE rule_id WHEN 'rule4' THEN active END) OVER (
             PARTITION BY item_no, item_type ORDER BY dt, ACTIVE DESC
           ),
           0
         ) AS rule4
  FROM   table_name
         UNPIVOT (
           dt FOR active IN ( active_from AS 1, active_to AS -1 )
         )
)
MATCH_RECOGNIZE(
  PARTITION BY item_no, item_type
  ORDER BY dt, rule1 DESC, rule2 DESC
  MEASURES
    FIRST(dt) AS active_from,
    PREV(rule4) AS prev_rule4,
    NEXT(dt) AS active_to,
    NEXT(rule4) AS next_rule4
  PATTERN ( active_rules+ )
  DEFINE active_rules AS rule1 > 0 AND rule2 > 0 AND rule3 > 0 AND rule4 = 0
)

其中,对于样本数据:

CREATE TABLE table_name (Item_no, item_type, active_from, active_to, rule_id) AS
  SELECT 10001, 'SAR', DATE '2023-01-01', DATE '2023-01-31', 'rule1' FROM DUAL UNION ALL
  SELECT 10001, 'SAR', DATE '2023-02-01', DATE '2023-02-28', 'rule1' FROM DUAL UNION ALL
  SELECT 10001, 'SAR', DATE '2023-01-01', DATE '9999-12-31', 'rule2' FROM DUAL UNION ALL
  SELECT 10001, 'SAR', DATE '2023-02-01', DATE '2023-02-28', 'rule3' FROM DUAL UNION ALL
  SELECT 10001, 'SAR', DATE '2023-02-01', DATE '2023-12-31', 'rule3' FROM DUAL UNION ALL
  SELECT 10001, 'SAR', DATE '2023-01-01', DATE '2023-02-03', 'rule4' FROM DUAL;
  • 注意:这与问题中的样本数据不同,因为问题中的样本将返回零行,因为rule4行覆盖了所有rule1rule3行。示例数据已更改,因此返回一行。*

输出:
| 项目编号|项目类型|ACTIVE_FROM| ACTIVE_TO|
| - -----|- -----|- -----|- -----|
| 10001| SAR| 2019 -02- 13 00:00:01| 2019 -02-28 00:00:00|
fiddle
通过更改MATCH_RECOGNIZE部分的DEFINE子句,您可以对前面问题的答案进行类似的更改,以获得您想要实现的其他逻辑的结果。

相关问题