2014-01-18 52 views
0

我需要一些帮助COALESCE。动态传递列凝聚

语法:COALESCE(Col1,Col2,Col3...)这意味着每一次我将不得不写里面列名作为参数的时间。

我的问题是我们可以动态传递的列名这个功能呢?因为列中的列数不断变化。

感谢, 希德

+2

您的设计听起来可能没有正常化。如果列数不断变化,并且列代表足够类似的东西,那么您可以使用'COALESCE'。 Col1,Col2,Col3等代表什么? –

+0

嗨马丁 - 每列包含父子元数据,但以不齐整的层次结构(楼梯)格式。由于其中有单元格为NULL,所以我试图向左移动数据并填充空单元格。现在由于层次结构的变化,我可能每次都有不同数量的列。 – user3209759

+0

请提供您的数据和期望结果的样本。 –

回答

0

铱听起来像是你有一堆列,并且要值到左侧,NULL s移动到右侧。

您可以通过每个值前计数的非NULL值的数目,然后使用case语句来赋值做到这一点。以下显示了四列的代码:

select (case when col1_n = 1 then col1 
      when col2_n = 1 then col2 
      when col3_n = 1 then col3 
      when col4_n = 1 then col4 
     end) as col1, 
     (case when col2_n = 2 then col2 
      when col3_n = 2 then col3 
      when col4_n = 2 then col4 
     end) as col2, 
     (case when col3_n = 3 then col3 
      when col4_n = 3 then col4 
     end) as col3, 
     (case when col4_n = 4 then col4 
     end) as col4 
from (select t.*, 
      (case when col1 is not null then 1 end) as col1_n, 
      ((case when col1 is not not null then 1 else 0 end) + 
       (case when col2 is not null then 1 end) 
      ) as col2_n, 
      ((case when col1 is not not null then 1 else 0 end) + 
       (case when col2 is not null then 1 else 0 end) + 
       (case when col3 is not null then 1 end) 
      ) as col3_n, 
      ((case when col1 is not not null then 1 else 0 end) + 
       (case when col2 is not null then 1 else 0 end) + 
       (case when col3 is not null then 1 else 0 end) + 
       (case when col4 is not null then 1 end) 
      ) as col4_n    
     from t 
    ) t; 

您可以在SQL小提琴(here)上看到此作品。

如果您有一个独特的id for each,您还可以取消转发数据,使用row_number()并重新传输数据。

+0

谢谢Gordon的回复。似乎上面的代码是为了知道(固定)的列数?我的表格中的列数不断变化。你能告诉我,如果我可以动态地将列传递给COALESCE吗? – user3209759

+0

@ user3209759。 。 。一个表具有固定数量的列,即SQL定义。这听起来像你可能需要动态SQL或者重新设计的应用程序。从表中添加和删除列的应用程序听起来像一个糟糕的设计。 –

+0

我的表格最多有20列。其中可以说我有10列的数据,剩余的单元将被替换为NULL。我想我将不得不在硬编码col1到col20在COALESCE而不是传递非NULL的列。我也会看到你所建议的动态SQL选项。谢谢... – user3209759