如何包含在某一天毫无意义的值(APEX)
How to include values that count nothing on certain day (APEX)
我有这个查询:
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 或我的查询中是否有办法包含未计算在内的天数?
如评论所述,使用一种行生成器技术,您将创建一个“日历”table 并将其与包含您正在显示的数据的 table 进行外部连接。
像这样(见代码中的评论):
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
@Littlefoot 的回答很完美。但这里有一种厚颜无耻的方式来获得类似 table 的格式匹配 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
仅适用于 oracle。但我认为您仍然可以使用递归 cte 在其他支持递归 cte 的 DBMS 中获得类似的结果。
我添加了一个 with 子句来生成过去 31 天,然后我离开加入了你的基地 table,如下所示。
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
;
我有这个查询:
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 或我的查询中是否有办法包含未计算在内的天数?
如评论所述,使用一种行生成器技术,您将创建一个“日历”table 并将其与包含您正在显示的数据的 table 进行外部连接。
像这样(见代码中的评论):
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
@Littlefoot 的回答很完美。但这里有一种厚颜无耻的方式来获得类似 table 的格式匹配 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
仅适用于 oracle。但我认为您仍然可以使用递归 cte 在其他支持递归 cte 的 DBMS 中获得类似的结果。
我添加了一个 with 子句来生成过去 31 天,然后我离开加入了你的基地 table,如下所示。
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
;