如何每小时计算比率?

时间:2018-09-18 13:46:52

标签: sql oracle

我在执行查询时对我的进一步动作有所了解。

我有两个表“ A”(日期,响应,b_id)“ B”(id,国家/地区)。我需要计算存在响应的条目的小时数与特定日期条目总数的每小时比率。最终选择应由“小时”,“比率”列组成。

SELECT COUNT(*) FROM A WHERE RESPONSE IS NOT NULL//counting entries with response
SELECT COUNT(*) FROM A//counting total number of entries
  1. 如何计算比率?我应该为此创建一个单独的变量吗?
  2. 如何计算一天中的每个小时?我应该像个循环一样使吗? +如何获得日期的“小时”部分?
  3. 选择小时和计数比率的最佳方法是什么?我应该为此单独制作一张桌子吗?

我很新,可以进行复杂的查询,所以我很乐意提供各种帮助

3 个答案:

答案 0 :(得分:2)

您可以按照以下步骤进行操作:

select to_char(datecol, 'HH24') as hour,
       count(response) as has_response, count(*) as total,
       count(response) / count(*) as ratio
from a
where datecol >= date '2018-09-18' and datecol < date '2018-09-19'
group by to_char(datecol, 'HH24');

您也可以使用avg()来做到这一点-这也很有趣:

select to_char(datecol, 'HH24'),
       avg(case when response is not null then 1.0 else 0 end) as ratio
from a
where datecol >= date '2018-09-18' and datecol < date '2018-09-19'
group by to_char(datecol, 'HH24')

在这种情况下,这需要更多的输入。

答案 1 :(得分:0)

   SELECT withResponses.hour,
       withResponses.cnt AS withResponse,
       alls.cnt AS AllEntries,
       (withResponses.cnt / alls.cnt) AS ratio
FROM
  ( SELECT to_char(d, 'DD-MM-YY - HH24') || ':00 to :59 ' hour,
           count(*) AS cnt
   FROM A
   WHERE RESPONSE IS NOT NULL
   GROUP BY to_char(d, 'DD-MM-YY - HH24') || ':00 to :59 ' ) withResponses,

  ( SELECT to_char(d, 'DD-MM-YY - HH24') || ':00 to :59 ' hour,
           count(*) AS cnt
   FROM A
   GROUP BY to_char(d, 'DD-MM-YY - HH24') || ':00 to :59 ' ) alls
WHERE alls.hour = withResponses.hour ;

SQLFiddle:http://sqlfiddle.com/#!4/c09b9/2

答案 2 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE A ( dt, response, b_id ) AS
  SELECT DATE '2018-09-18' + INTERVAL '00:00' HOUR TO MINUTE, NULL, 1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '00:10' HOUR TO MINUTE, 'A',  1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '00:20' HOUR TO MINUTE, 'B',  1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '01:00' HOUR TO MINUTE, 'C',  1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '01:10' HOUR TO MINUTE, 'D',  1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '02:00' HOUR TO MINUTE, NULL, 1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '03:00' HOUR TO MINUTE, 'E',  1 FROM DUAL UNION ALL
  SELECT DATE '2018-09-18' + INTERVAL '05:10' HOUR TO MINUTE, 'F',  1 FROM DUAL;

查询1

SELECT b_id,
       TO_CHAR( TRUNC( dt, 'HH' ), 'YYYY-MM-DD HH24:MI:SS' ) AS hour,
       COUNT(RESPONSE) AS total_response_per_hour,
       COUNT(*)        AS total_per_hour,
       total_response_per_day,
       total_per_day,
       COUNT(response) / total_response_per_day AS ratio_for_responses,
       COUNT(*) / total_per_day AS ratio
FROM   (
  SELECT A.*,
         COUNT(RESPONSE) OVER ( PARTITION BY b_id, TRUNC( dt ) ) AS total_response_per_day,
         COUNT(*) OVER ( PARTITION BY b_id, TRUNC( dt ) ) AS total_per_day
  FROM   A
)
GROUP BY
       b_id,
       total_per_day,
       total_response_per_day,
       TRUNC( dt, 'HH' )
ORDER BY
       TRUNC( dt, 'HH' )

Results

| B_ID |                HOUR | TOTAL_RESPONSE_PER_HOUR | TOTAL_PER_HOUR | TOTAL_RESPONSE_PER_DAY | TOTAL_PER_DAY | RATIO_FOR_RESPONSES | RATIO |
|------|---------------------|-------------------------|----------------|------------------------|---------------|---------------------|-------|
|    1 | 2018-09-18 00:00:00 |                       2 |              3 |                      6 |             8 |  0.3333333333333333 | 0.375 |
|    1 | 2018-09-18 01:00:00 |                       2 |              2 |                      6 |             8 |  0.3333333333333333 |  0.25 |
|    1 | 2018-09-18 02:00:00 |                       0 |              1 |                      6 |             8 |                   0 | 0.125 |
|    1 | 2018-09-18 03:00:00 |                       1 |              1 |                      6 |             8 | 0.16666666666666666 | 0.125 |
|    1 | 2018-09-18 05:00:00 |                       1 |              1 |                      6 |             8 | 0.16666666666666666 | 0.125 |