SQL: ?从 3NF 表创建一个视图,使其看起来像单行重复组

SQL: ?Create a VIEW from 3NF tables to look like a single row Repeating Group

我们有一个遗留 table,包含重复组。

我们想切换到规范化的父子,然后创建一个看起来与旧 table 完全一样的视图。我们可以在不影响的情况下逐步升级系统。

我在思考如何有效地编写视图时遇到了一些麻烦 - 它背后有大量数据(数百万行)。我们可以在 DB2 and/or Teradata

中完成

Sample data

OLD_TABLE

 PID 
 CID_COUNT -- count of values used 
 CID_1
 CVALUE_1
 CID_2
 CVALUE_2

NEW_PARENT_TABLE

PID
CID_COUNT

NEW_CHILD_TABLE

PID
CID
CVALUE

假设您使用的是 Db2 11.1.0.0 或更高版本,或者 Db2 Warehouse,这段代码会给您想要的答案。

DROP TABLE NEW_PARENT_TABLE;
DROP TABLE NEW_CHILD_TABLE;

CREATE  OR REPLACE VIEW OLD_TABLE (PID, NAME, CID_COUNT, CID_1, CVALUE_1,  CID_2, CVALUE_2)
AS (VALUES 
    (123,'FRED',2,1   ,'Stilton',2  ,'Cheddar')
,   (124,'MARY',1,1   ,'Butter' ,null,null)
,   (125,'BOB', 0,null,null     ,null,null)
)
;
CREATE TABLE NEW_PARENT_TABLE (
      PID INT NOT NULL PRIMARY KEY
    , NAME CHAR(4) NOT NULl UNIQUE
    , CID_COUNT SMALLINT NOT NULL
    ) ORGANIZE BY ROW
;
INSERT INTO NEW_PARENT_TABLE
SELECT DISTINCT PID, NAME, CID_COUNT FROM OLD_TABLE
;
CREATE TABLE NEW_CHILD_TABLE (
      PID INT NOT NULL REFERENCES NEW_PARENT_TABLE
    , CID INT NOT NULL
    , CVALUE VARCHAR(16) NOT NULL
    , PRIMARY KEY ( PID, CID )
    ) ORGANIZE BY ROW
;
INSERT INTO NEW_CHILD_TABLE
SELECT N.*
FROM OLD_TABLE O
,   TABLE(VALUES (O.PID, O.CID_1, O.CVALUE_1)
            ,    (O.PID, O.CID_2, O.CVALUE_2)
            ) AS N (PID, CID, CVALUE )
WHERE
    N.CID IS NOT NULL;

CREATE OR REPLACE VIEW NEW_VIEW AS
SELECT PID, CID_COUNT
,      MAX(CASE WHEN CID = 1 THEN CID    END) AS CID_1
,      MAX(CASE WHEN CID = 1 THEN CVALUE END) AS CVALUE_1
,      MAX(CASE WHEN CID = 2 THEN CID    END) AS CID_2
,      MAX(CASE WHEN CID = 2 THEN CVALUE END) AS CVALUE_2
 FROM NEW_PARENT_TABLE
 LEFT JOIN NEW_CHILD_TABLE USING (PID)
 GROUP BY PID, CID_COUNT
 ;
 SELECT * FROM NEW_VIEW

 PID CID_COUNT CID_1 CVALUE_1 CID_2 CVALUE_2
 --- --------- ----- -------- ----- --------
 123         2     1 Stilton      2 Cheddar
 124         1     1 Butter    NULL NULL
 125         0  NULL NULL      NULL NULL

如果在 DB2(对于 LUW)10.5 上,请在 NEW_VIEW 中使用 ON 而不是 USING 并限定列。如果在 DB2 10.1 或更低版本上,还删除 ORGANIZE BY ROW