Oracle:将名称值对扁平化为表

时间:2009-04-17 14:10:39

标签: oracle dynamic-sql denormalization

我希望有人可以提供一些建议,以便更轻松地解决这个问题。我正在努力创建一个高度规范化的数据集的平面视图。扁平化的目的是提供一个普通人可以用来开发报告的视图。源数据包含几个表,如下所示:

CREATE TABLE VARIABLES  ( 
    VARIABLE_ID INT NOT NULL IDENTITY, 

    VARIABLE_NAME VARCHAR(100) NOT NULL, 

    VARIABLE_DATATYPE VARCHAR(100) NOT NULL, 

    PRIMARY KEY (VARIABLE_ID), 

    UNIQUE (VARIABLE_NAME,VARIABLE_DATATYPE) 
)

CREATE TABLE RECORD_VALUES (
    RUN_ID INT NOT NULL REFERENCES RUNS (RUN_ID) ON DELETE CASCADE, 

    VARIABLE_ID INT NOT NULL REFERENCES VARIABLES(VARIABLE_ID) ON DELETE CASCADE, 

    RECORD_ID VARCHAR(100) NOT NULL, 

    VARIABLE_VALUE VARCHAR(1000), 

    PRIMARY KEY (RUN_ID,VARIABLE_ID,RECORD_ID)
)

记录值表中的variable_id对应于原始输入流中的一个变量,例如地址或帐户余额。对于包含12个变量的输入记录,记录值表中将有12行。

原始流程的输入包括不同宽度和变量名称的记录。它们被拆分为record_values表中的名称/值元组。我正在编写一个过程来将变量重新组合回一个看起来像

的记录
run_id
record_id (which is actually an underlying account number)
variable_value_1
variable_value_2
...
variable_value_n

我目前的方法是通过查找给定运行集的唯一变量(此处不重要的详细信息)动态构建表,然后构建将创建表的SQL字符串。

我的挑战是如何从原始数据高效加载生成的工作表。由于变量的名称和数量因run_id而异,我能想到的唯一方法是通过以下方式:

create a cursor for the list of variables
for each variable in the list
   create a cursor to find all the record values for that variable
   for each record value
       update the appropriate record/column in the work table
   end
end

这将永远运行,因为父表有100百万行。

有没有人知道如何生成一种方法,我可以用它来为每个目的地行进行一次更新?

为了避免任何人跳过原始表的设计 - 有商业理由这样做。我不喜欢它,但有充分的理由这样做。

感谢您提供的任何想法。

安德鲁

1 个答案:

答案 0 :(得分:2)

Oracle 10g及以上:

SELECT  DISTINCT run_id, record_id, val1, val2, ..., val12
FROM    record_values
MODEL
IGNORE NAV
PARTITION BY
        (run_id, record_id)
DIMENSION BY
        (variable_id)
MEASURES
        (val, 0 AS val1, 0 AS val2, ..., 0 AS val12)
RULES UPDATE
        (
        val1[ANY] = val[1], /* Put real variable ID's in the square brackets */
        val2[ANY] = val[2],
        ...,
        val12[ANY] = val[12]
        )