嗨,我认为我有这张表
create table process(process_id serial, state text);
insert into process(process_id, state) values(1, 'DONE'),
(2, 'DONE'),
(3, 'DONE'),
(4, 'FAILED');
现在如果您运行:
select distinct(state),count(*) a from process group by state;
你会得到两行:FAILED 1,DONE 3 我想要的是获得失败进程的百分比= FAILED /(FAILED + DONE)。
答案 0 :(得分:2)
您可以使用case ... when
。要避免整数除法,您还需要将其中一个数字转换为float:
select cast(count(case state when 'FAILED' then 1 end) as float) / count(*) a
from process;
或者,您也可以使用nullif
:
select cast(count(nullif(state, 'DONE')) as float) / count(*) a
from process;
答案 1 :(得分:2)
Postgres中的一种方法使用Dim ws As Worksheet
Dim dataRng As Range
Dim dic As Variant, arr As Variant
Dim cnt As Long
Set ws = Sheets("1")
With ws
lastrow = .Cells(.Rows.Count, "D").End(xlUp).Row 'get last row in Column D
Set dataRng = .Range("D2:D" & lastrow) 'range for Column D
Set dic = CreateObject("Scripting.Dictionary")
arr = dataRng.Value
For i = 1 To UBound(arr)
dic(arr(i, 1)) = dic(arr(i, 1)) + 1
Next
.Range("M2").Resize(dic.Count, 1) = Application.WorksheetFunction.Transpose(dic.keys) 'uniques data from Column D
.Range("Q2").Resize(dic.Count, 1) = Application.WorksheetFunction.Transpose(dic.items)
cnt = dic.Count
For i = 2 To cnt + 1
.Range("N" & i & ":P" & i).Formula = "=SUMIF($D$2:$D$" & lastrow & ",$M" & i & ",E$2:E$" & lastrow & ")/" & dic(.Range("M" & i).Value)
.Range("R" & i).Formula = "=IF(INDEX($I$2:$I$" & lastrow & ",MATCH($M" & i & ",$D$2:$D$" & lastrow & ",0))=0,N" & i & ","""")"
.Range("S" & i).Formula = "=IF(INDEX($I$2:$I$" & lastrow & ",MATCH($M" & i & ",$D$2:$D$" & lastrow & ",0))=0,Q" & i & ","""")"
.Range("T" & i).Formula = "=IF($S" & i & ">0,SUMPRODUCT(($D$2:$D$" & lastrow & "=$M" & i & ")*(($J$2:$J$" & lastrow & "-$E$2:$E$" & lastrow & ")>3%)),"""")"
Next i
.Range("M" & i).Value = "Grand Total"
.Range("N" & i & ":P" & i).Formula = "=AVERAGE(N2:N" & cnt + 1 & ")"
.Range("Q" & i).Formula = "=SUM(Q2:Q" & cnt + 1 & ")"
.Range("R" & i).Formula = "=AVERAGE(R2:R" & cnt + 1 & ")"
.Range("S" & i & ":T" & i).Formula = "=SUM(S2:S" & cnt + 1 & ")"
.Range("N2:T" & .Cells(.Rows.Count, "M").End(xlUp).Row + 1).Value = .Range("N2:T" & .Cells(.Rows.Count, "M").End(xlUp).Row + 1).Value
End With
:
avg()
如果您有其他状态,可以添加select avg( (state = 'FAILED')::int )
from process;
。
答案 2 :(得分:1)
使用FILTER
缩小计算哪些行:
SELECT CAST(count(*) FILTER (WHERE state = 'FAILED') AS float)
/ count(*)
FROM process
WHERE state in ('FAILED', 'DONE');
有关详细信息,请参阅PostgreSQL文档中的Aggregate Expressions。第一个计数转换为float
以防止在分割时出现整数截断。
FAILED
或DONE
中的状态过滤器是在WHERE
子句而不是聚合过滤器中完成的,以确保state
列上的任何索引都可以使用