如果通过SQL(Excelstyle)对列进行规则

问题描述 投票:-2回答:2

在Excel中,可以编写允许以下计算的规则:

温恩意味着如果

所以基本上我计算是否使用了一个月(1-12)(在这种情况下有一个数字)。所以在二月有一个数字(1,44)意味着没有使用0。棘手的是,我还想计算是否连续几个月没有使用。所以7月必须是3,因为没有使用第5,6,7栏。有没有办法在SQL中这样做?

编辑

现在只有桌子上。 Auftr_Nr | 1 | 2 | 3等...我需要的是选择此表并添加12列未使用。在此表中,我想存储值。

sql excel oracle
2个回答
1
投票

你需要某种递归查询,下面是工作示例。

/*
with t(autr_nr, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12) as (
    select 10, 0, 1.44, 0, 1.392, 0, 0, 0, 1.406, 1.373, null, null, null from dual 
    union all
    select 20, 7, 9.97, 0, 0, 0, 1.892, 0, 5.406, 2.792, null, null, null from dual ),
*/
with unp as (
    select rownum rn, autr_nr, col, val 
      from t unpivot include nulls (val for col in 
        (c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12))),
cte (rn, autr_nr, col, val, nu) as (
    select rn, autr_nr, col, val, 
           case when val = 0 then 1 else 0 end 
      from unp where col = 'C01'
    union all    
    select unp.rn, unp.autr_nr, unp.col, unp.val, 
           case when unp.val = 0 then cte.nu + 1 else 0 end 
      from cte join unp on unp.autr_nr = cte.autr_nr and unp.rn = cte.rn + 1
)
select * 
  from (select autr_nr, col, nu from cte) 
  pivot (max(nu) for col in ('C01', 'C02', 'C03', 'C04', 'C05', 'C06', 
                             'C07', 'C08', 'C09', 'C10', 'C11', 'C12'))
  order by autr_nr

demo

子查询t模仿你的数据(我做了它有一些输入可以使用,它被评论,你不需要它在你的环境中),unp将行显示为列,递归cte构建连续零的计数器,最后查询将行更改为列。作为cte的替代品,您可以使用累积和(分析函数)。

结果:

AUTR_NR 'C01' 'C02' 'C03' 'C04' 'C05' 'C06' 'C07' 'C08' 'C09' 'C10' 'C11' 'C12'
------- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- 
     10     1     0     1     0     1     2     3     0     0     0     0     0
     20     0     0     1     2     3     0     1     0     0     0     0     0

1
投票

与@ PonderStibbon的方法不同,但不是递归的:

-- CTE just to generate your sample data
with your_table (auftr_nr, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12") as (
  select 10, 0, 1.440, 0, 1.392, 0, 0, 0, 1.406, 1.373, null, null, null from dual
)
-- end of CTE
select auftr_nr,
  "1_ORG", "2_ORG", "3_ORG", "4_ORG", "5_ORG", "6_ORG", "7_ORG", "8_ORG", "9_ORG", "10_ORG", "11_ORG", "12_ORG",
  "1_NEW", "2_NEW", "3_NEW", "4_NEW", "5_NEW", "6_NEW", "7_NEW", "8_NEW", "9_NEW", "10_NEW", "11_NEW", "12_NEW"
from (
    select auftr_nr, month, org,
      case
        when org is null then null
        when org = 0 then
          month - nvl(max(case when org != 0 then month end)
              over (partition by auftr_nr order by month), 0)
        else 0
        end as new
    from (
      select *
      from your_table
      unpivot (org for month in ("1" as 1, "2" as 2, "3" as 3, "4" as 4, "5" as 5, "6" as 6,
        "7" as 7, "8" as 8, "9" as 9, "10" as 10, "11" as 11, "12" as 12))
    )
)
pivot (sum(org) as org, sum(new) as new for (month) in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));

  AUFTR_NR      1_ORG      2_ORG      3_ORG      4_ORG      5_ORG      6_ORG      7_ORG      8_ORG      9_ORG     10_ORG     11_ORG     12_ORG      1_NEW      2_NEW      3_NEW      4_NEW      5_NEW      6_NEW      7_NEW      8_NEW      9_NEW     10_NEW     11_NEW     12_NEW
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
        10          0       1.44          0      1.392          0          0          0      1.406      1.373                                           1          0          1          0          1          2          3          0          0                                 

这是从原始表中取出行,将其取消,每月制作一行,使用分析函数查找每个月所需的新值(Stibbons先生提到的那个),然后将其全部转回单个行行。

您可以创建该查询的视图,这样您就不必在实际表中添加(和维护)额外的派生值。

如果你确实想要那些列,那就太乱了;每一个都可以是一个虚拟列,它可以查看自己的值以及所有“早期”列的值,这意味着它们会越来越复杂。对于第一个计算列,它将非常简单,例如:

case
  when "1" is null then null
  when "1" = 0 then 1
  else 0
end

但第二个会扩展到:

case
  when "2" is null then null
  when "2" = 0 then 1 + 
    case
      when "1" = 0 then 1
      else 0
    end
end

第三个:

case
  when "3" is null then null
  when "3" = 0 then 1 + 
    case
      when "2" = 0 then 1 +
        case
          when "1" = 0 then 1
          else 0
        end
      else 0
    end
  end

等等,所以你可以看到,在第十二列它会相当长,使得整个事情很难维持。视图可能更容易维护 - 您可能需要比较两种方法的成本。

© www.soinside.com 2019 - 2024. All rights reserved.