SQL:从3NF表创建VIEW看起来像单行重复组

时间:2018-08-24 07:10:45

标签: view db2 teradata database-normalization denormalization

我们有一个旧表,其中包含重复的组。

我们想交换到规范化的父级孩子,然后创建一个看起来与旧表完全相似的视图。我们可以逐步升级系统,而不会产生任何影响。

我在解决如何有效地编写视图时遇到了麻烦-它背后有很多数据(亿万行)。我们可以在DB2和/或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

1 个答案:

答案 0 :(得分:0)

假设您使用的是Db2 11.1.0.0或更高版本或Db2仓库,此代码将为您提供所需的答案。

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上,请在ON中使用USING而不是NEW_VIEW并限定列。如果在DB2 10.1或更低版本上,请同时删除ORGANIZE BY ROW