SQL Oracle - SUBQUERY 根据表条件有选择地从*不同*列中提取数据

问题描述 投票:0回答:1

直接进入。我们有表 (TABLE) 和审计表 (AUDITTABLE) 存储对主表的更改。

在表中,我们有如下条目:

身份证 姓名 已创建 位置ID 人员ID
1 犹他州 94年1月1日 35 1
2 俄亥俄州 95/02/01 42 5

将第 1 行的

LocationID
从 35 更改为 50,并将
PersonID
从 1 更改为 3 将记录在审核表中(为简洁起见,省略了一些列,还有诸如创建和创建者之类的项目来跟踪何时和由谁更改了值):

身份证 来源ID 钥匙 旧值
1 1 位置ID 35
2 1 人物 1

我正在编写一个查询,从审计表中提取数据:

SELECT
    sourceid AS ID,
    id AS EVENT_ID
    key AS COLUMN,
    oldvalue AS PREVIOUS_ENTRY
FROM
    AUDITTABLE

我想要在 select 中使用一个子查询,根据当前行的审计表中的 KEY(与主表列名称一对一匹配)来提取主表中当前存储的值。 我可以使用 Case 语句来完成此操作,但我有大约 100 个表来执行此操作,每个表都有唯一的列名(每个表有几十个列),这将是一场噩梦。

编辑

写完这篇我正在看推荐文章,似乎一切都指向写案例陈述。 如果这就是最终的答案,请让我知道这无法以我需要的方式实现,并且无需浪费时间编写示例案例陈述或联合查询 - 这完全符合我的技能范围,尽管这会带来身体上的痛苦接下来

我在想类似下面的东西(这显然不起作用,但显示了我想要实现的目标的总体思路)。

SELECT
    sourceid AS ID,
    id AS EVENT_ID
    key AS COLUMN,
    oldvalue AS PREVIOUS_ENTRY,
    (SELECT TABLE. || (SELECT TEMPAUDITTABLE.KEY 
                       FROM AUDITTABLE AS TEMPAUDITTABLE 
                       WHERE TEMPAUDITTABLE.SOURCEID = AUDITTABLE.SOURCEID) 
     FROM Table 
     WHERE Table.ID = Audittable.sourceid) AS Current_Value
FROM
    AUDITTABLE

我知道您可以从

USER_TAB_COLUMNS
获取表列名称,这可能是解决方案的一部分,但我不知道如何实现类似的东西。

如果我遗漏了一些明显的东西,我提前道歉。我在编写查询方面相当不错,但我大约 90% 是自学的,我的知识可能存在一些差距。

对于任何愿意帮助我指出正确方向的人,谢谢!

我尝试过谷歌、copilot、tech-on-the-net,并搜索堆栈溢出问题。我还参考了 SQL Oracle 的文档。

sql oracle correlated-subquery
1个回答
0
投票

为了使其通用,您需要使用动态 SQL。最简单的方法是一个简单的函数,它返回给定表、行和列的值。

create or replace function current_value(in_table_name in varchar2,in_row_column in varchar2, in_row_id in integer,in_select_column in varchar2)
  return varchar2
as
  var_result varchar2(4000);
begin
  execute immediate 'select max('||in_select_column||') from '||in_table_name||' where '||in_row_column||' = :id' into var_result using in in_row_id;
  return var_result;
end;

为了获得良好的性能,您需要确保行标识列在每个表中都建立了索引。然后你只需查询:

SELECT
    sourceid AS ID,
    id AS EVENT_ID
    key AS COLUMN,
    oldvalue AS PREVIOUS_ENTRY,
    current_value('MYTABLE','MY_ID_COL',id,key) current_value
FROM AUDITTABLE  
© www.soinside.com 2019 - 2024. All rights reserved.