2

我有这个查询:

SELECT  
COUNT(ID) AS FREQ,
TO_CHAR(TRUNC(CREATED_AT),'DD-MON') DATES
FROM TICKETS
WHERE TRUNC(CREATED_AT) > TRUNC(SYSDATE) - 32
GROUP BY TRUNC(CREATED_AT)
ORDER BY TRUNC(CREATED_AT) ASC

这会计算过去一个月每天创建的工单数量。
结果如下所示:(
前 10 行)

FREQ    DATES
3   28-DEC
4   04-JAN
8   05-JAN
1   06-JAN
4   07-JAN
5   08-JAN
2   11-JAN
6   12-JAN
3   13-JAN
8   14-JAN

我创建的折线图如下所示:

折线图


问题是没有创建票证的日子(特别是周末),这条线直接到创建票证的那一天。

在 APEX 或我的查询中是否有办法包括未计算的天数?

4

3 回答 3

2

正如所评论的,使用行生成器技术之一,您将创建一个“日历”表并将其与包含您正在显示的数据的表外部连接。

像这样的东西(见代码中的注释):

SQL> with yours (amount, datum) as
  2    -- your sample table
  3    (select 100, date '2021-01-01' from dual union all
  4     select 200, date '2021-01-03' from dual union all
  5     select 300, date '2021-01-07' from dual
  6    ),
  7  minimax as
  8    -- MIN and MAX date (so that they could be used in row generator --> CALENDAR CTE (below)
  9    (select min(datum) min_datum,
 10            max(datum) max_datum
 11     from yours
 12    ),
 13  calendar as
 14    -- calendar, from MIN to MAX date in YOUR table
 15    (select min_datum + level - 1 datum
 16     from minimax
 17     connect by level <= max_datum - min_datum + 1
 18    )
 19  -- final query uses outer join
 20  select c.datum,
 21         nvl(y.amount, 0) amount
 22  from calendar c left join yours y on y.datum = c.datum
 23  order by c.datum;

DATUM          AMOUNT
---------- ----------
01.01.2021        100
02.01.2021          0
03.01.2021        200
04.01.2021          0
05.01.2021          0
06.01.2021          0
07.01.2021        300

7 rows selected.

SQL>

应用于您当前的查询:

WITH
   minimax
   AS
      -- MIN and MAX date (so that they could be used in row generator --> CALENDAR CTE (below)
      (SELECT MIN (created_at) min_datum, MAX (created_at) max_datum
         FROM tickets),
   calendar
   AS
      -- calendar, from MIN to MAX date in YOUR table
      (    SELECT min_datum + LEVEL - 1 datum
             FROM minimax
       CONNECT BY LEVEL <= max_datum - min_datum + 1)
  -- final query uses outer join
  SELECT COUNT (t.id) AS freq, TO_CHAR (TRUNC (c.datum), 'DD-MON') dates
    FROM calendar c LEFT JOIN tickets t ON t.created_at = c.datum
   WHERE TRUNC (t.created_at) > TRUNC (SYSDATE) - 32
GROUP BY TRUNC (c.datum)
ORDER BY dates ASC
于 2021-01-27T08:28:33.190 回答
1

@Littlefoot 答案是完美的。但这是一种获得格式匹配 OP 输出的类似表格的厚颜无耻的方法。为此使用一个简单的 cte。

   WITH cte AS (
     SELECT To_Char(Trunc(SYSDATE - ROWNUM),'DD-MON') dtcol
       FROM DUAL 
    CONNECT BY ROWNUM < 366
    )
    SELECT * FROM cte

这是db<>fiddle

然后你可以简单地加入这个 cte 来填补空白日期。因为原始输出列date看起来像一个字符串列。
connect by仅适用于甲骨文。但我认为您仍然可以使用递归 cte 在其他支持递归 cte 的其他 DBMS 中获得类似的结果。

于 2021-01-27T08:35:43.827 回答
1

我添加了一个 with 子句来生成最后 31 天,然后我离开了加入您的基表,如下所示。

with last_31_days as (
select trunc(sysdate) - 32 + level dt from dual connect by trunc(sysdate) - 32 + level < trunc(sysdate)
)
SELECT  
nvl(COUNT(t.ID), 0) AS FREQ,
TO_CHAR(
        nvl(TRUNC(t.CREATED_AT), a.dt)
    ,'DD-MON') DATES
FROM last_31_days a 
    LEFT JOIN TICKETS t 
        ON TRUNC(t.CREATED_AT) = a.dt 
GROUP BY nvl(TRUNC(t.CREATED_AT), a.dt)
ORDER BY 2 ASC
;
于 2021-01-27T08:44:38.080 回答