非规范化表。 SQL选择

时间:2014-05-23 13:25:38

标签: sql db2

据我所知,我有一个非规范化的表。以下是一些表格列表:

... C, F, T, C1, F1, T1, .... C8, T8, F8.....

是否可以在行中选择这些值?
这样的事情:

C, F, T
C1, F1, T1
......
C8, F8, T8

3 个答案:

答案 0 :(得分:4)

您可以使用union all

轻松完成
select C, F, T from table t
union all
select C1, F1, T1 from table t
union all
. . .
select C8, F8, T8 from table t;

请注意使用union all代替unionunion执行自动重复删除,因此您可能无法使用union获取所有值(以及操作更昂贵)。

这通常会导致表格被扫描9次。如果你有一个大表,还有其他方法可能更有效。

编辑:

更有效的方法可能是cross joincase。在DB2中,我认为这将是:

select (case n.n when 0 then C
                 when 1 then C1
                  . . .
                 when 8 then C8
        end) as C,
       (case n.n when 0 then F
                 when 1 then F1
                  . . .
                 when 8 then F8
        end) as F,
       (case n.n when 0 then T
                 when 1 then T1
                  . . .
                 when 8 then T8
        end) as T       
from table t cross join
     (select 0 as n from sysibm.sysdummy1 union all select 1 from sysibm.sysdummy1 union all . . .
      select 9 from sysibm.sysdummy1
     ) n;

这可能看起来更多,但它应该只读取更大的表一次,其余的工作是内存操作。

答案 1 :(得分:1)

select c,f,t from table
union all
select c1,f1,t1 from table
union all
select c8,f8,t8 from table

确保按每个SELECT语句的WHERE子句进行过滤。

答案 2 :(得分:0)

类似于Gordons的一个技巧是使用LATERAL来避免多次扫描:

with t(c1,t1,f1,c2,t2,f2) as ( values (1,2,3,4,5,6) ) 
select y.c, y.t, y.f 
from t x 
cross join lateral ( values (x.c1, x.t1, x.f1)
                          , (x.c2, x.t2, x.f2) ) y(c,t,f)

C           T           F          
----------- ----------- -----------
          1           2           3
          4           5           6