我有一张表格,显示我项目每一步的统计数据。它看起来像这样:
ITEM STEP_1 STEP_2 STEP_3 STEP_4 STEP_5
----- -------- -------- -------- -------- --------
1 OK NOK OK NOK IN ANALYSIS
2 OK OK OK OK N/A
3 NOK NOK NOK NOK NOK
我想要做的是使用新的进度列创建一个视图。像这样:
ITEM STEP_1 STEP_2 STEP_3 STEP_4 STEP_5 Progress
----- -------- -------- -------- -------- -------- -----------
1 OK NOK OK NOK ANALYSIS 40%
2 OK OK OK OK N/A 100%
3 NOK NOK NOK NOK NOK 0%
百分比值是通过将每个步骤中的“OK”或“N / A”相加并除以步骤总数(在本例中为5)得到的。
可以这样做吗?
编辑1。:
喜欢这个吗?
ITEM STEPs STATUS
----- -------- --------
1 Step_1 OK
1 Step_2 NOK
1 Step_3 NOK
1 Step_4 ANALYSIS
1 Step_5 OK
Edit.2:
以下是我正在进行规范化的简化版本:
SELECT
T.*
FROM
( SELECT DISTINCT
ITEM_ID,
(SELECT FINAL_STATUS
FROM book_new b
WHERE a.ITEM_ID = b.ITEM_ID
AND b.STEPS = 'STEP_1'
) AS STEP_1 ,
(SELECT FINAL_STATUS
FROM book_new b
WHERE a.ITEM_ID = b.ITEM_ID
AND b.STEPS = 'STEP_2'
) AS STEP_2 ,
(SELECT FINAL_STATUS
FROM book_new b
WHERE a.ITEM_ID = b.ITEM_ID
AND b.STEPS = 'STEP_3'
AND ROWNUM = 1
) AS STEP_3 ,
(SELECT FINAL_STATUS
FROM book_new b
WHERE a.ITEM_ID = b.ITEM_ID
AND b.STEPS = 'STEP_4'
AND ROWNUM = 1
) AS STEP_4 ,
(SELECT FINAL_STATUS
FROM book_new b
WHERE a.ITEM_ID = b.ITEM_ID
AND b.STEPS = 'STEP_5'
AND ROWNUM = 1
) AS STEP_5
FROM book_new A
) T
答案 0 :(得分:1)
只需定义您要使用的计算并包含别名:
name
如果您希望计算根据belongs_to
列的数量动态更改,那么您运气不佳。 RDBMS通常不是为处理动态列而设计的。
此外,正如duffymo指出的那样,在正确标准化的设计中,这将更加容易。这也可以让你动态调整步数。
答案 1 :(得分:1)
如果您从非规范化数据开始,您可以使用分析计数查询找到每个项目的“正常”步骤百分比:
select item_id, steps, final_status,
100 * count(case when final_status in ('OK', 'N/A') then final_status end)
over (partition by item_id) -- analytic function with windowing clause
/ count(steps) over (partition by item_id) as percent_ok
from book_new
order by item_id, steps;
ITEM_ID STEPS FINAL_ST PERCENT_OK
---------- ------ -------- ----------
1 STEP_1 OK 40
1 STEP_2 NOK 40
1 STEP_3 NOK 40
1 STEP_4 ANALYSIS 40
1 STEP_5 OK 40
2 STEP_1 OK 100
...
然后,您可以将其转换为所需的表格格式;在11gR2或更高版本上,您可以使用内置数据透视运算符:
select item_id, a_step as step_1, b_step as step_2, c_step as step_3,
d_step as step_4, e_step as step_5, percent_ok || '%' as progress
from (
select item_id, steps, final_status,
100 * count(case when final_status in ('OK', 'N/A') then final_status end)
over (partition by item_id)
/ count(steps) over (partition by item_id) as percent_ok
from book_new
)
pivot (max(final_status) as step for (steps) in ('STEP_1' as a, 'STEP_2' as b,
'STEP_3' as c, 'STEP_4' as d, 'STEP_5' as e))
order by item_id;
ITEM_ID STEP_1 STEP_2 STEP_3 STEP_4 STEP_5 PROGRESS
---------- -------- -------- -------- -------- -------- --------------------------
1 OK NOK NOK ANALYSIS OK 40%
2 OK OK OK OK N/A 100%
3 NOK NOK NOK NOK NOK 0%
在早期版本中,您可以使用聚合函数在案例表达式上手动转动数据:
select item_id,
max(case when steps = 'STEP_1' then final_status end) as step_1,
max(case when steps = 'STEP_2' then final_status end) as step_2,
max(case when steps = 'STEP_3' then final_status end) as step_3,
max(case when steps = 'STEP_4' then final_status end) as step_4,
max(case when steps = 'STEP_5' then final_status end) as step_5,
percent_ok || '%' as progress
from (
select item_id, steps, final_status,
100 * count(case when final_status in ('OK', 'N/A') then final_status end)
over (partition by item_id)
/ count(steps) over (partition by item_id) as percent_ok
from book_new
)
group by item_id, percent_ok
order by item_id;
得到相同的结果(无论如何11g都是这样做的。)
您使用子查询的方法效率不会非常高,因为您多次查询同一个表。但是,通过这种方法,您仍然可以使用@ Allan的答案 - 只需更改外部SELECT T.* FROM
以列出列并以相同方式进行计算。
您可以在文档中详细了解analytic functions和pivoting。
顺便说一句,您也可以稍微改变计算进度的方式。如果一个步骤是N / A那么根据它计算可能没有意义;您可以改为将内部查询更改为忽略这些,仅用于计算:
select item_id, steps, final_status,
100 * count(case when final_status = 'OK' then final_status end)
over (partition by item_id)
/ count(case when final_status != 'N/A' then final_status end)
over (partition by item_id) as percent_ok
from book_new
这对您的样本数据没有任何影响,但如果您有一个N / A项目,而其他项目除了OK之外,那么百分比就会上升。这可能不是你想要的,但它是一个选择......