Oracle:基于变量和历史记录表获取价格

如何解决Oracle:基于变量和历史记录表获取价格

我有一个表“变量”和一个表“ variables_history”,如下所示

create table variables
( 
    variables_id number,variables_name varchar2(50),variables_value varchar2(50),variables_updated_at timestamp
);


create table variables_history
( 
    variables_id number,variables_hist_updated_at timestamp
);

历史记录是由触发器生成的,如下所示。

CREATE OR REPLACE EDITIONABLE TRIGGER "myuser"."trigger_variables_update" 
  AFTER UPDATE ON myuser.variables
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW

BEGIN
  IF :old.variables_value <> :new.variables_value THEN
    INSERT INTO myuser.variables_history
      (variables_id,variables_name,variables_value,variables_hist_updated_at
    VALUES
      (variables_id,:old.variables_name,:old.variables_value,old.variables_updated_at);
  END IF;
END trigger_variables_update;

我还有一张桌子,上面有所有的维护

create table maintenance
( 
    maintenance_id number,maintenance_status varchar2(20),maintenance_date timestamp
);

我需要基于maintenance_date的变量和variables_updated_at或variables_hist_updated_at

生成一个带有maintenance_price的输出

像这样


WITH variables_data as
( SELECT 1 variables_id,'maintenance_price' variables_name,'30.00' variables_value,'2020-08-01 05:00:00.000' variables_updated_at from dual),variables_history_data as
(
SELECT 1 variables_id,'15.90' variables_value,'2019-10-01 11:30:00.000' variables_hist_updated_at from dual union all
SELECT 1 variables_id,'10.50' variables_value,'2020-01-01 01:00:00.000' variables_hist_updated_at from dual union all
SELECT 1 variables_id,'20.30' variables_value,'2020-05-01 12:30:00.000' variables_hist_updated_at from dual
),maintenance_data as
(
SELECT 1 maintenance_id,'COMPLETE' maintenance_status,'2019-02-01 00:30:00.000' maintenance_date from dual union all
SELECT 2 maintenance_id,'2019-05-01 01:30:00.000' maintenance_date from dual union all
SELECT 3 maintenance_id,'2019-11-01 02:30:00.000' maintenance_date from dual union all
SELECT 4 maintenance_id,'2020-07-10 05:30:00.000' maintenance_date from dual union all
SELECT 5 maintenance_id,'FAILED' maintenance_status,'2020-08-02 11:30:00.000' maintenance_date from dual
SELECT 6 maintenance_id,'2020-08-20 11:30:00.000' maintenance_date from dual
)

Select 
    m.maintenance_id,to_char(m.maintenance_date,'yyyy/mm/dd') as maintenance_date
    v.variables_value
from 
    maintenances m
    join variables v on m.maintenance_date >= v.variables_updated_at
    join variables_history vh on m.maintenance_date < variables_hist_updated_at
        where maintenance_status = 'COMPLETE';

这个查询只是一个例子,我知道它是错误的

我需要这样的输出(并考虑该变量可能具有新的更新)。 “ variable_value”必须是生成维护时的值。

maintenance_id | maintenance_date | variables_value |
---------------+------------------+-----------------+
            1  |        2019-02-01|           15.90 |
---------------+------------------+-----------------+
            2  |        2019-05-01|           15.90 |
---------------+------------------+-----------------+
            3  |        2019-11-01|           10.50 |
---------------+------------------+-----------------+
            4  |        2020-07-10|           20.30 |
---------------+------------------+-----------------+
            6  |        2020-08-20|           30.00 |
---------------+------------------+-----------------+

解决方法

据我了解,您的数据(在Matthew McPeak的帮助下),历史记录表存储了价格过时的日期,而另一方面,“实时”表存储了价格生效的日期。

您可以通过两个横向连接来解决这个问题:

select 
    m.maintenance_id,to_char(m.maintenance_date,'yyyy/mm/dd') as maintenance_date,v.*,vh.*,coalesce(v.variables_value,vh.variables_value) as variables_value
from maintenances m
outer apply(
    select v.variables_value
    from variables_data v
    where v.variables_updated_at <= m.maintenance_date
) v
outer apply (
    select vh.variables_value
    from variables_history_data vh
    where vh.variables_hist_updated_at > m.maintenance_date
    order by vh.variables_hist_updated_at
    fetch first 1 row only
) vh
where m.maintenance_status = 'COMPLETE'
order by 1;

有关示例数据,the query returns

MAINTENANCE_ID | MAINTENANCE_DATE | VARIABLES_VALUE
-------------: | :--------------- | --------------:
             1 | 2019/02/01       |            15.9
             2 | 2019/05/01       |            15.9
             3 | 2019/11/01       |            10.5
             4 | 2020/07/10       |            null
             6 | 2020/08/20       |              30

请注意,示例数据中存在故障。历史记录表中应有一行时间戳,该时间戳与实时数据的当前时间戳相对应-因此,maintenance_id 4与任何内容都不匹配。

,

您可以使用UNION ALL合并表,然后使用LAG / LEAD查找最新(或下一个)值:

SELECT *
FROM   (
  SELECT maintenance_id,COALESCE(
           variables_value,LAG( variables_value,1 ) IGNORE NULLS OVER ( ORDER BY maintenance_date ),LEAD( variables_value,1 ) IGNORE NULLS OVER ( ORDER BY maintenance_date )
         ) AS variables_value,maintenance_date
  FROM   (
    SELECT maintenance_id,NULL AS variables_value,maintenance_date
    FROM   maintenances
    WHERE  maintenance_status = 'COMPLETE'
    UNION ALL
    SELECT NULL,variables_value,variables_updated_at
    FROM   variables
    UNION ALL
    SELECT NULL,variables_hist_updated_at
    FROM   variables_history
  )
)
WHERE maintenance_id IS NOT NULL;

其中,为您的示例数据:

CREATE TABLE variables ( variables_id,variables_name,variables_updated_at ) as
SELECT 1,'maintenance_price',30.00,TIMESTAMP '2020-08-01 05:00:00.000' from dual;

CREATE TABLE variables_history ( variables_id,variables_hist_updated_at ) as
SELECT 1,15.90,TIMESTAMP '2019-10-01 11:30:00.000' from dual union all
SELECT 1,10.50,TIMESTAMP '2020-01-01 01:00:00.000' from dual union all
SELECT 1,20.30,TIMESTAMP '2020-05-01 12:30:00.000' from dual;

CREATE TABLE maintenances ( maintenance_id,maintenance_status,maintenance_date ) as
SELECT 1,'COMPLETE',TIMESTAMP '2019-02-01 00:30:00.000' from dual union all
SELECT 2,TIMESTAMP '2019-05-01 01:30:00.000' from dual union all
SELECT 3,TIMESTAMP '2019-11-01 02:30:00.000' from dual union all
SELECT 4,TIMESTAMP '2020-07-10 05:30:00.000' from dual union all
SELECT 5,'FAILED',TIMESTAMP '2020-08-02 11:30:00.000' from dual union all
SELECT 6,TIMESTAMP '2020-08-20 11:30:00.000' from dual;

输出:

MAINTENANCE_ID | VARIABLES_VALUE | MAINTENANCE_DATE            
-------------: | --------------: | :---------------------------
             1 |            15.9 | 01-FEB-19 00.30.00.000000000
             2 |            15.9 | 01-MAY-19 01.30.00.000000000
             3 |            15.9 | 01-NOV-19 02.30.00.000000000
             4 |            20.3 | 10-JUL-20 05.30.00.000000000
             6 |              30 | 20-AUG-20 11.30.00.000000000

如果您交换LAGLEAD(以选择下一个值而不是上一个值):

SELECT *
FROM   (
  SELECT maintenance_id,variables_hist_updated_at
    FROM   variables_history
  )
)
WHERE maintenance_id IS NOT NULL;

然后输出为:

MAINTENANCE_ID | VARIABLES_VALUE | MAINTENANCE_DATE            
-------------: | --------------: | :---------------------------
             1 |            15.9 | 01-FEB-19 00.30.00.000000000
             2 |            15.9 | 01-MAY-19 01.30.00.000000000
             3 |            10.5 | 01-NOV-19 02.30.00.000000000
             4 |              30 | 10-JUL-20 05.30.00.000000000
             6 |              30 | 20-AUG-20 11.30.00.000000000

db 提琴here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-