在Excel中,可以编写允许以下计算的规则:
温恩意味着如果
所以基本上我计算是否使用了一个月(1-12)(在这种情况下有一个数字)。所以在二月有一个数字(1,44)意味着没有使用0。棘手的是,我还想计算是否连续几个月没有使用。所以7月必须是3,因为没有使用第5,6,7栏。有没有办法在SQL中这样做?
编辑
现在只有桌子上。 Auftr_Nr | 1 | 2 | 3等...我需要的是选择此表并添加12列未使用。在此表中,我想存储值。
你需要某种递归查询,下面是工作示例。
/*
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
子查询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
与@ 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
等等,所以你可以看到,在第十二列它会相当长,使得整个事情很难维持。视图可能更容易维护 - 您可能需要比较两种方法的成本。