- 需求描述
對一些業務數據以報表的形式進行展示,在項目上線前統計數據不準確(忽略了節假日的統計)和查詢速度慢。統計的是職員處理業務的執行率(默認發公告給你,你在正常工作日的一天之內處理就是及時處理)。 - 原始版本
日期格式的操作用的是to_char,導致索引沒有命中,查詢較慢。報表的頁面引入多餘的js,使得後臺數據返回前臺,前臺加載數據的時候還要幾秒。 - 優化後的版本
涉及到的日期格式用to_date,處理及時不及時考慮到節假日。
SELECT DECODE(TT.TASK_NUM_TOTAL, NULL, 0, TT.TASK_NUM_TOTAL) TASK_NUM_TOTAL,
DECODE(TT.TASK_NUM_COMP, NULL, 0, TT.TASK_NUM_COMP) TASK_NUM_COMP,
DECODE(TT.TASK_NUM_TIME, NULL, 0, TT.TASK_NUM_TIME) TASK_NUM_TIME,
DECODE(TT.TASK_NUM_TOTAL,
0,
0,
round((TT.TASK_NUM_TIME * 100) / TT.TASK_NUM_TOTAL, 2)) || '%' TASK_NUMBER_TIME_PERCENT,
DECODE(TT.TASK_NUM_TOTAL,
0,
0,
round((TT.TASK_NUM_TIME * 100) / TT.TASK_NUM_TOTAL, 2)) TASK_NUMBER_TIME_SCALE,
TT.FULLNAME,
TT.USERID
FROM (SELECT DECODE(T.TASK_NUM_TOTAL, NULL, 0, T.TASK_NUM_TOTAL) TASK_NUM_TOTAL,
DECODE(T.TASK_NUM_COMP, NULL, 0, T.TASK_NUM_COMP) TASK_NUM_COMP,
DECODE(T.TASK_NUM_TIME, NULL, 0, T.TASK_NUM_TIME) TASK_NUM_TIME,
V.FULLNAME,
V.USERID
FROM (SELECT A.TASK_NUM_TOTAL,
B.TASK_NUM_COMP,
C.TASK_NUM_TIME,
A.USERID
FROM (SELECT COUNT(O.TC_TASK_CONTENT_ID) TASK_NUM_TOTAL, O.TASK_HANDLE_PERSON USERID
FROM TC_TASK_CONTENT O
WHERE 1 = 1
AND O.TASK_CREATE_DATE >= TO_DATE(?, 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE < TO_DATE(?, 'YYYY-MM-DD')+1
GROUP BY O.TASK_HANDLE_PERSON) A,
(SELECT COUNT(O.TC_TASK_CONTENT_ID) TASK_NUM_COMP, O.TASK_HANDLE_PERSON USERID
FROM TC_TASK_CONTENT O
WHERE O.TASK_STATE = '2'
AND O.TASK_CREATE_DATE >= TO_DATE(?, 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE < TO_DATE(?, 'YYYY-MM-DD')+1
GROUP BY O.TASK_HANDLE_PERSON) B,
(SELECT COUNT(O.TC_TASK_CONTENT_ID) TASK_NUM_TIME, O.TASK_HANDLE_PERSON USERID
FROM TC_TASK_CONTENT O
WHERE O.TASK_STATE = '2'
AND O.TASK_CREATE_DATE >= TO_DATE(?, 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE < TO_DATE(?, 'YYYY-MM-DD')+1
AND TRUNC(O.ACTUAL_FINISH_DATE-O.TASK_CREATE_DATE)<=1
GROUP BY O.TASK_HANDLE_PERSON) C
WHERE A.USERID = B.USERID(+)
AND B.USERID = C.USERID(+)) T,
USERS_ORGS UO,
USER_ U,
(SELECT ORGANIZATIONID
FROM ORGANIZATION_ T
CONNECT BY PRIOR T.ORGANIZATIONID = T.PARENTORGANIZATIONID
START WITH ORGANIZATIONID = '"+MapUtil.getString(inputData, "ORGANIZATIONID")+"') ORG,
V_USER_ORG V
WHERE UO.ORGANIZATIONID = ORG.ORGANIZATIONID
AND T.USERID(+) = U.USERID
AND U.USERID = UO.USERID
AND V.USERID = U.USERID
UNION ALL
SELECT SUM(DECODE(T.TASK_NUM_TOTAL, NULL, 0, T.TASK_NUM_TOTAL)) TASK_NUM_TOTAL,
SUM(DECODE(T.TASK_NUM_COMP, NULL, 0, T.TASK_NUM_COMP)) TASK_NUM_COMP,
SUM(DECODE(T.TASK_NUM_TIME, NULL, 0, T.TASK_NUM_TIME)) TASK_NUM_TIME,
'合計' FULLNAME,
111111 USERID
FROM (SELECT A.TASK_NUM_TOTAL,
B.TASK_NUM_COMP,
C.TASK_NUM_TIME,
A.USERID
FROM (SELECT COUNT(O.TC_TASK_CONTENT_ID) TASK_NUM_TOTAL, O.TASK_HANDLE_PERSON USERID
FROM TC_TASK_CONTENT O
WHERE 1 = 1
AND O.TASK_CREATE_DATE >= TO_DATE(?, 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE < TO_DATE(?, 'YYYY-MM-DD')+1
GROUP BY O.TASK_HANDLE_PERSON) A,
(SELECT COUNT(O.TC_TASK_CONTENT_ID) TASK_NUM_COMP, O.TASK_HANDLE_PERSON USERID
FROM TC_TASK_CONTENT O
WHERE O.TASK_STATE = '2'
AND O.TASK_CREATE_DATE >= TO_DATE(?, 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE < TO_DATE(?, 'YYYY-MM-DD')+1
GROUP BY O.TASK_HANDLE_PERSON) B,
(SELECT COUNT(O.TC_TASK_CONTENT_ID) TASK_NUM_TIME, O.TASK_HANDLE_PERSON USERID
FROM TC_TASK_CONTENT O
WHERE O.TASK_STATE = '2'
AND O.TASK_CREATE_DATE >= TO_DATE(?, 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE < TO_DATE(?, 'YYYY-MM-DD')+1
AND TRUNC(O.ACTUAL_FINISH_DATE-O.TASK_CREATE_DATE)<=1
GROUP BY O.TASK_HANDLE_PERSON) C
WHERE A.USERID = B.USERID(+)
AND B.USERID = C.USERID(+)) T,
USERS_ORGS UO,
USER_ U,
(SELECT ORGANIZATIONID
FROM ORGANIZATION_ T
CONNECT BY PRIOR T.ORGANIZATIONID = T.PARENTORGANIZATIONID
START WITH ORGANIZATIONID = '"+MapUtil.getString(inputData, "ORGANIZATIONID")+"') ORG,
V_USER_ORG V
WHERE T.USERID(+) = U.USERID
AND U.USERID = UO.USERID
AND UO.ORGANIZATIONID = ORG.ORGANIZATIONID
AND V.USERID = U.USERID) TT
- 最終版本
WITH ALL_ORG AS
(SELECT ORGANIZATIONID,
DECODE(LEVEL, 2, ORGANIZATIONID, 3, T.PARENTORGANIZATIONID) THIRDID
FROM ORGANIZATION_ T
CONNECT BY PRIOR T.ORGANIZATIONID = T.PARENTORGANIZATIONID
START WITH ORGANIZATIONID = '5272'),
ORG_SUM AS
(SELECT DECODE(T.TASK_NUM_TOTAL, NULL, 0, T.TASK_NUM_TOTAL) TASK_NUM_TOTAL,
DECODE(T.TASK_NUM_COMP, NULL, 0, T.TASK_NUM_COMP) TASK_NUM_COMP,
DECODE(T.TASK_NUM_TIME, NULL, 0, T.TASK_NUM_TIME) TASK_NUM_TIME,
(SELECT OZ.NAME
FROM ORGANIZATION_ OZ
WHERE OZ.ORGANIZATIONID = T.THIRDID) FULLNAME,
T.THIRDID
FROM (SELECT A.TASK_NUM_TOTAL,
A.TASK_NUM_COMP,
A.TASK_NUM_TIME,
A.THIRDID
FROM (SELECT SUM(1) TASK_NUM_TOTAL,
SUM(CASE
WHEN TRUNC(O.ACTUAL_FINISH_DATE -
O.TASK_CREATE_DATE) <= 1 THEN
1
ELSE
0
END) TASK_NUM_TIME,
SUM(DECODE(TASK_STATE, '2', 1, 0)) TASK_NUM_COMP,
O.TASK_HANDLE_PERSON USERID, TT.THIRDID
FROM TC_TASK_CONTENT O,USERS_ORGS UO,ALL_ORG TT
WHERE O.TASK_HANDLE_PERSON = UO.USERID
AND UO.ORGANIZATIONID = TT.ORGANIZATIONID
AND TT.THIRDID IS NOT NULL
AND O.TASK_CREATE_DATE >= TO_DATE('2017-01-01', 'YYYY-MM-DD')
AND O.TASK_CREATE_DATE <
TO_DATE('2017-12-31', 'YYYY-MM-DD') + 1
GROUP BY TT.THIRDID) A) T),
OGR_ALL AS
(SELECT S.*
FROM ORG_SUM S)
SELECT DECODE(TT.TASK_NUM_TOTAL, NULL, 0, TT.TASK_NUM_TOTAL) TASK_NUM_TOTAL,
DECODE(TT.TASK_NUM_COMP, NULL, 0, TT.TASK_NUM_COMP) TASK_NUM_COMP,
DECODE(TT.TASK_NUM_TIME, NULL, 0, TT.TASK_NUM_TIME) TASK_NUM_TIME,
DECODE(TT.TASK_NUM_TOTAL,
0,
0,
ROUND((TT.TASK_NUM_TIME * 100) / TT.TASK_NUM_TOTAL, 2)) || '%' TASK_NUMBER_TIME_PERCENT,
DECODE(TT.TASK_NUM_TOTAL,
0,
0,
ROUND((TT.TASK_NUM_TIME * 100) / TT.TASK_NUM_TOTAL, 2)) TASK_NUMBER_TIME_SCALE,
TT.FULLNAME,
TT.THIRDID
FROM OGR_ALL TT
附帶查詢的結果圖:
5. 討論
判斷某一天是否屬於上班時間?知道某一天,這一天的5個工作日是幾月幾號?現在對於工作日的判斷是將一年的日期放進表裏面維護,判斷5個工作後是幾月幾號用的是遞歸。感覺這樣的做法很繁瑣而且效率很慢,但是沒有什麼其他的好辦法。