如何在 sql 中找到中位数

How to find median in sql

我有以下 sql 查询,它给出了按月、周和日分组的总数 h_time。相反,我想要月、周和日的中位数 h_time。我如何在 Oracle SQL 中执行此操作?

 SELECT DAY,

MEDIAN(H_TIME) AS HANDLE_TIME

FROM(
    select 
MONTH, WEEK, DAY,

    CASE 
        WHEN C.JOINED IS NOT NULL
            THEN (NVL(C.TOTAL_TALK,0) + NVL(C.TOTAL_HOLD,0) + (NVL((C.DATETIME - C.START_DATETIME)*86400,0)) )/86400 
            ELSE 0 END AS H_TIME

from TABLE1 C


LEFT JOIN TABLE2 S
ON S.ID = C.ID
where c.direct = 'Inbound'
)

where UPPER(ITEM1) like 'SOMETHING%' 

GROUP BY


DAY

输出:

DAY              HANDLE_TIME
14-APR-17   .00567129629629629629629629629629629629629
15-APR-17   0
17-APR-17   0
17-APR-17   .00422453703703703703703703703703703703703
19-APR-17   .00269675925925925925925925925925925925925
19-APR-17   0
19-APR-17   0
19-APR-17   .00824074074074074074074074074074074074074

尝试替换:

SUM(H_TIME) AS HANDLE_TIME

来自:

MEDIAN(H_TIME) AS HANDLE_TIME

(第 3 行)


编辑: 对于月份,替换为:

select 
MONTH, WEEK, DAY,

作者:

select 
MONTH,

并且:

GROUP BY

MONTH
,WEEK
,DAY

作者:

GROUP BY 
MONTH


对于周数,替换为:

select 
MONTH, WEEK, DAY,

作者:

select 
MONTH, WEEK,

并且:

GROUP BY

MONTH
,WEEK
,DAY

作者:

GROUP BY 
MONTH
,WEEK

问题不在于 median() 函数,而是 group by 列。

Oracle DATE 数据类型实际上是 DATETIME,例如2017-05-24 08:09:11。所以在比较日期时,我们必须考虑时间因素。

最简单的方法是截断日期值,将时间设置为午夜。所以在你的情况下看起来像这样:

SELECT trunc(day) as DAY,
       MEDIAN(H_TIME) AS H_TIME
FROM (
    ...
)
group by trunc(day)

此解决方案优于使用 to_char() 删除时间元素,因为数据类型仍为 DATE。因此,如果您对结果 order by trunc(day) 进行排序,您将获得预期的日历顺序,而对 to_char(day) 进行排序会给出意想不到的字母数字顺序。

尝试在 group by 和 select 语句中使用 to_char(DAY)

您的问题可能来自 DATE 类型携带的时间部分(即使您没有明确设置它)。

要删除它,您可以使用 trunc 函数。

替换:

SELECT DAY,

作者:

SELECT trunc(DAY)

并且:

GROUP BY DAY

作者:

GROUP BY trunc(DAY)