我想从垂直数据库布局传输数据,如下所示:
--------------------- | ID | Type | Value | --------------------- | 1 | 10 | 111 | --------------------- | 1 | 14 | 222 | --------------------- | 2 | 10 | 333 | --------------------- | 2 | 25 | 444 | ---------------------
到横向:
--------------------------------- | ID | Type10 | Type14 | Type25 | --------------------------------- | 1 | 111 | 222 | | --------------------------------- | 2 | 333 | | 444 | ---------------------------------
创建布局不是问题,但数据库相当大,有数百万条目,如果花费很多时间,查询就会被取消。
如何有效地完成这项工作(以便不取消查询)。
答案 0 :(得分:0)
将其分解为更小的块,并且不要将整个事物包装在单个事务中。首先,创建表,然后将旧表中的插入组执行到新表中。按ID范围插入,例如,在足够小的块中,它不会压倒数据库的日志并花费太长时间。
答案 1 :(得分:0)
with t as
(
select 1 as ID, 10 as type, 111 as Value from dual
union
select 1, 14, 222 from dual
union
select 2, 10, 333 from dual
union
select 2, 25, 444 from dual
)
select ID,
max(case when type = 10 then Value else null end) as Type10,
max(case when type = 14 then Value else null end) as Type14,
max(case when type = 25 then Value else null end) as Type25
from t
group by id
返回你想要的东西,我觉得这是更好的方法。 请注意,max函数只是执行group by子句,任何组函数都可以在这里使用(如sum,min ...)
答案 2 :(得分:0)
垂直表 - 也称为实体 - 属性 - 值反模式 - 总是成为问题,有时在实施后不久。如果你还没有这样做,请看看Joe Celko对这个策略的评价,你会看到更多证据证明这种方法有多麻烦。我会在那里停下来,因为你是那个知道来这个网站的聪明人,而不是那个在你的数据库中犯下EAV表的内疚但善意的人。
处理这种类型的表的选项并不漂亮,正如您所说,随着生产查询所需的数据量的增加,它们会变得更糟/更慢。
构建未记录的已声明全局临时表(DGTT)并保留已提交的行,并使用它来暂存EAV表内容的水平版本。 DGTT适用于这种数据挖掘,因为它们不会产生任何记录开销。
使用传统的CASE和MAX()分组,如上一条建议所示。问题是每次在您的EAV表中引入新的TYPE时,查询都会更改。
使用DB2的SQL-XML发布功能将垂直数据转换为XML。这是一个使用您提供的表名和列名的示例:
WITH t(id, type, value) as (
VALUES (1,10,111), (1,14,222), (2,10,333), (2,25,444)
)
SELECT
XMLSERIALIZE( CONTENT
XMLELEMENT(NAME "outer",
XMLATTRIBUTES(id AS "id"),
XMLAGG(XMLELEMENT(NAME attr ,
XMLATTRIBUTES(type as "typeid"), value) ORDER BY type)
) AS VARCHAR(1024)
)
FROM t as t group by id;
SQL-XML方法的好处是,EAV表处理的任何新值都不需要重写SQL来支持这些值。