0

我在 FreeNode IRC 中有一个非常好的人引导我更接近答案。

我现在使用的查询是:

SELECT st.staff_id
     , ROUND (100.0 * ( sum (case when s.code in ('10401','10402','10403') then 1
                                      else 0 end)/count(s.code)), 1) as successes
    from notes n join services s on n.zrud_service=s.zzud_service
            join staff st on n.zrud_staff = st.zzud_staff
    WHERE s.code IN ( '10401','10402','10403','10405')
    AND n.date_service BETWEEN (now() - '30 days'::interval)::timestamp AND now()
    group by st.staff_id;

(我确实尝试过 /count(*) 以及其他一些方法)

它不会出错,并将结果显示为 100.0 或 0 我只对按员工分组的代码运行查询并得到不同的结果。一名员工在过去一个月内出院了 23 人,其中 8 人不成功 (10405) 这给出了 34.7% 的成功率。但查询显示 0%。

这令人费解。有人有建议吗?

原始问题

我需要能够查看在 30 天内成功出院的百分比。这是一个按代码显示放电的查询。我知道我可以在 postgresql 中使用“除法”方法,但我只能将它与两个单独的列一起使用。有人可以协助向我展示如何在列中划分数据吗?我需要做类似的事情:10401'+'10402'+'10403' / 10401'+'10402'+'10403'+'10405'

SELECT n.date_creation, g.name AS Group, s.staff_id, n.date_service, c.client_id,
       c.name_lastfirst_cs AS Client, q.code 
FROM notes n, clients c, groups g, staff s,services q 
WHERE n.visibility_flag = 1 -- valid note
AND notes.date_service BETWEEN (now() - '30 days'::interval)::timestamp AND now();
AND c.zzud_client = n.zrud_client AND n.zrud_group = g.zzud_group  
AND n.zrud_staff = s.zzud_staff 
AND q.code IN ('10401','10402','10403','10405')  -- 10405 is unsuccessful discharge
AND n.zrud_service = q.zzud_service AND n.zrud_staff = ? ORDER BY n.date_service

如果我这样重写查询:

SELECT g.name AS Group, s.staff_id, c.client_id,
       c.name_lastfirst_cs AS Client, q.code 
FROM notes n, clients c, groups g, staff s,services q 
WHERE n.visibility_flag = 1 -- valid note
AND notes.date_service BETWEEN (now() - '30 days'::interval)::timestamp AND now();
AND c.zzud_client = n.zrud_client AND n.zrud_group = g.zzud_group  
AND n.zrud_staff = s.zzud_staff 
AND n.zrud_service = q.zzud_service AND n.zrud_staff = ? ORDER BY n.date_service

或者,我可以使用“SUM”运算符来代替所有的 + 吗?

我将查询更改为:

SELECT g.name AS Group, s.staff_id AS Staff
SUM(CASE WHEN q.code BETWEEN '10401' AND '10405' THEN 1 ELSE 0 END) / SUM(CASE WHEN q.code       BETWEEN '10401' AND '10405' THEN 0 ELSE 1 END)
 AS success_ratio FROM FROM notes n, clients c, groups g, staff s,services q  
 AND n.date_service BETWEEN (now() - '30 days'::interval)::timestamp AND now()
AND q.code IN ('10401','10402','10403','10405')
AND c.zzud_client = n.zrud_client AND n.zrud_group = g.zzud_group  
AND n.zrud_staff = s.zzud_staff 
AND n.zrud_service = q.zzud_service AND s.staff_id = 'BATTNEAL1026' ORDER BY n.date_service
 GROUP BY s.staff_id

并得到这个错误:

ERROR:  syntax error at or near "SUM"
LINE 2: SUM(CASE WHEN q.code BETWEEN '10401' AND '10405' THEN 1 ELSE...
        ^

********** Error **********

ERROR: syntax error at or near "SUM"
SQL state: 42601
Character: 45
4

1 回答 1

0

您的问题是两个bigint/integer数字的除法。由于您的结果始终 < 0,因此结果为 0 或 1。这里:

sum (case when s.code in ('10401','10402','10403') then 1 else 0 end)
    /count(s.code)

先乘以100.0
中的小数位100.0强制在 中进行计算numeric,从而保留小数部分。

通过其他一些修改和格式化,它可能如下所示:

SELECT st.staff_id
      ,round((count(s.code IN ('10401','10402','10403') OR NULL) * 100.0)
            / count(*), 1) AS successes
FROM   notes    n 
JOIN   services s  ON s.zzud_service = n.zrud_service
JOIN   staff    st ON st.zzud_staff = n.zrud_staff
WHERE  s.code IN ('10401','10402','10403','10405')
AND    n.date_service BETWEEN (now() - '30 days'::interval) AND now()
GROUP  BY st.staff_id;
于 2013-10-23T03:43:42.663 回答