很抱歉,这个问题的措辞很奇怪。不确定如何措辞,但这是上下文:
我正在开发一个应用程序,该应用程序显示一些有关用户从我的Web服务器发出请求时使用单个应用程序的频率的数据。我们获取数据的方式是每次加载起始页时,都会在加载之日递增一个名为WEB_TRACKING的数据表。因此,数据中存在很多漏洞,例如,某个应用程序可能在9月1日被大量使用,而在9月2日则没有使用。我想做的是添加命中值为0的孔。这就是我想出的。
Select HIT_DATA.DATE_ACCESSED, HIT_DATA.APP_ID, HIT_DATA.NAME, WORKDAYS.BENCH_DAYS, NVL(HIT_DATA.HITS, 0) from (
select DISTINCT( TO_CHAR(WEB.ACCESS_TIME, 'MM/DD/YYYY')) as BENCH_DAYS
FROM WEB_TRACKING WEB
) workDays
LEFT join (
SELECT TO_CHAR(WEB.ACCESS_TIME, 'MM/DD/YYYY') as DATE_ACCESSED, APP.APP_ID, APP.NAME,
COUNT(WEB.IP_ADDRESS) AS HITS
FROM WEB_TRACKING WEB
INNER JOIN WEB_APP APP ON WEB.APP_ID = APP.APP_ID
WHERE APP.IS_ENABLED = 1 AND (APP.APP_ID = 1 OR APP.APP_ID = 2)
AND (WEB.ACCESS_TIME > TO_DATE('08/04/2018', 'MM/DD/YYYY')
AND WEB.ACCESS_TIME < TO_DATE('09/04/2018', 'MM/DD/YYYY'))
GROUP BY TO_CHAR(WEB.ACCESS_TIME, 'MM/DD/YYYY'), APP.APP_ID, APP.NAME
ORDER BY TO_CHAR(WEB.ACCESS_TIME, 'MM/DD/YYYY'), app_id DESC
) HIT_DATA ON HIT_DATA.DATE_ACCESSED = WORKDAYS.BENCH_DAYS
ORDER BY WORKDAYS.BENCH_DAYS
它返回日期范围之间的所有日期,甚至将空匹配数转换为0。但是,它为应用程序ID和应用程序名称返回空值。这很有意义,而且我了解如何为1个应用程序提供默认值。我希望有人可以帮助我弄清楚如何针对多个应用程序进行操作。
基本上,我得到了(在仅使用一个应用程序的情况下):
| APP_ID | NAME | BENCH_DAYS | HITS |
| ------ | ---------- | ---------- | ---- |
| NULL | NULL | 08/04/2018 | 0 |
| 1 | test_app | 08/05/2018 | 1 |
| NULL | NULL | 08/06/2018 | 0 |
但是我想要这个(有多个应用程序):
| APP_ID | NAME | BENCH_DAYS | HITS |
| ------ | ---------- | ---------- | ---- |
| 1 | test_app | 08/04/2018 | 0 |<- these 0's are converted from null
| 1 | test_app | 08/05/2018 | 1 |
| 1 | test_app | 08/06/2018 | 0 | <- these 0's are converted from null
| 2 | prod_app | 08/04/2018 | 2 |
| 2 | prod_app | 08/05/2018 | 0 | <- these 0's are converted from null
因此,在此长篇文章中再次重申该问题。我应该如何填充此查询,以便它可以填补日期中的漏洞,而且还可以重用应用程序名称和ID并填充该信息?
答案 0 :(得分:1)
您需要一个日期列表,该列表可能来自数字生成器而不是表格(如果该表格有孔,您的报告也将如此)
例如,过去30天的每个日期:
select trunc(sysdate-30) + level as bench_days from dual connect by level < 30
使用TRUNC而不是将日期转换为字符串以缩短时间
现在您有了日期列表,要添加重复的应用程序ID和名称:
select * from
(select trunc(sysdate-30) + level as bench_days from dual connect by level < 30) dat
CROSS JOIN
(select app_id, name from WEB_APP WHERE APP.IS_ENABLED = 1 AND APP_ID in (1, 2) app
现在,您可以将所有日期与所有应用程序交叉使用。 2个应用程序和30天的时间将通过交叉联接产生60行结果集。左加入您的统计数据,然后分组/计数/求和/汇总...
select app.app_id, app.name, dat.artificialday, COALESCE(stat.ct, 0) as hits from
(select trunc(sysdate-30) + level as artificialday from dual connect by level < 30) dat
CROSS JOIN
(select app_id, name from WEB_APP WHERE APP.IS_ENABLED = 1 AND APP_ID in (1, 2) app
LEFT JOIN
(SELECT app_id, trunc(access_time) accdate, count(ip_address) ct from web_tracking group by app_id, trunc(access_time)) stat
ON
stat.app_id = app.app_id AND
stat.accdate = dat.artificialday
您不必以这种方式编写查询/将您的分组作为子查询进行操作,我只是以这种方式表示它,以使您考虑以块为单位的数据,您可以独立构建并稍后再连接在一起,以建立更全面的区块