sql大賽第四期
/*
*解題思路:題目需要求解按照公司、服務、當天人數來計算費用。
*為了減少記錄數,不按照每天一計算,按照一段時間計算的方式求解。
*比如:在1號到5號某個公司、服務的人數都是一樣的,那麼記錄一條記錄即可。公司、服務、時間段、*人數
*求解步驟:
*1、求出所有的時間點包括輸入的引數
*2、按照時間點來將一條記錄分割成多條記錄
*3、按照公司、服務、時間段分組、求出費用
*/
WITH
INSERT_TIME--輸入的引數:兩個時間點
AS
(
SELECT TO_DATE(:P_START_DATE,'YYYYMMDD') DATE1,TO_DATE(:P_END_DATE,'YYYYMMDD')+1 DATE2 FROM DUAL
),
ALL_TIME--所有的時間點,包括輸入的兩個時間點
AS
(
SELECT SU.COMPANY_ID,S.SERVICE_ID,S.START_DATE DT1
FROM SERVICE_USAGE S,SERVICE_USERS SU
WHERE S.USER_ID=SU.USER_ID
UNION
SELECT SU.COMPANY_ID,S.SERVICE_ID,S.END_DATE+1
FROM SERVICE_USAGE S,SERVICE_USERS SU
WHERE S.USER_ID=SU.USER_ID
UNION
SELECT C.COMPANY_ID,S.SERVICE_ID,DATE1
FROM INSERT_TIME,COMPANIES C,SERVICES S
UNION
SELECT C.COMPANY_ID,S.SERVICE_ID,DATE2
FROM INSERT_TIME,COMPANIES C,SERVICES S
),
ALL_GROUP--根據所有的時間點,將一條記錄分成多條,根據上邊求出的所有時間段(使用LEAD函式)
AS
(
SELECT SU.COMPANY_ID,S.USER_ID,S.SERVICE_ID,S.START_DATE,S.END_DATE+1 END_DATE,ALT.DT1,
LEAD(DT1,1) OVER(PARTITION BY SU.COMPANY_ID, S.USER_ID, S.SERVICE_ID ORDER BY ALT.DT1 ) DT2
FROM SERVICE_USAGE S,SERVICE_USERS SU,ALL_TIME ALT,INSERT_TIME IT
WHERE S.USER_ID=SU.USER_ID
AND SU.COMPANY_ID=ALT.COMPANY_ID
AND S.SERVICE_ID=ALT.SERVICE_ID
AND S.START_DATE<=ALT.DT1
AND S.END_DATE+1>=ALT.DT1
AND ALT.DT1>=IT.DATE1
AND ALT.DT1<=IT.DATE2
),
GROUP_COM--按照公司、服務、時段分組,求出人數及時間間隔
AS
(
SELECT AA.COMPANY_ID,AA.SERVICE_ID,DT1,DT2,COUNT(1) PEOPLE_NUM,DT2-DT1 DATES
FROM ALL_GROUP AA
WHERE AA.DT2 IS NOT NULL
GROUP BY AA.COMPANY_ID,AA.SERVICE_ID,DT1,DT2
),
BELONG_GROUP--求出屬於哪個歸檔
AS
(
SELECT BB.COMPANY_ID,BB.SERVICE_ID,PEOPLE_NUM,DT1,DT2,DATES,
CASE WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=1 THEN 1 WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=2 THEN 2 WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=3 THEN 3 WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=4 THEN 4 END LEV
FROM GROUP_COM BB,SERVICE_RATES SR
WHERE BB.COMPANY_ID=SR.COMPANY_ID
AND BB.SERVICE_ID=SR.SERVICE_ID
AND ((PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=1)
OR (PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=2)
OR (PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=3)
OR (PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=4)
)
),
all_money--求出費用
AS
(
SELECT CC.COMPANY_ID,CC.SERVICE_ID,LEV,SUM(DATES*PEOPLE_NUM*SR.RATE) SINGLE_FEE
FROM BELONG_GROUP CC,SERVICE_RATES SR
WHERE CC.COMPANY_ID=SR.COMPANY_ID
AND CC.SERVICE_ID=SR.SERVICE_ID
AND LEV=SR.CATEGORY_ID
GROUP BY CC.COMPANY_ID,CC.SERVICE_ID,LEV
)--行專列
SELECT DD.COMPANY_ID,C.COMPANY_NAME,DD.SERVICE_ID,S.SERVICE_NAME,
MAX(DECODE(LEV,1,SINGLE_FEE)),
MAX(DECODE(LEV,2,SINGLE_FEE)),
MAX(DECODE(LEV,3,SINGLE_FEE)),
MAX(DECODE(LEV,4,SINGLE_FEE)),
SUM(SINGLE_FEE)
FROM all_money DD,COMPANIES C,SERVICES S
WHERE DD.COMPANY_ID=C.COMPANY_ID
AND DD.SERVICE_ID=S.SERVICE_ID
GROUP BY DD.COMPANY_ID,C.COMPANY_NAME,DD.SERVICE_ID,S.SERVICE_NAME
ORDER BY DD.COMPANY_ID,C.COMPANY_NAME,DD.SERVICE_ID,S.SERVICE_NAME;
*解題思路:題目需要求解按照公司、服務、當天人數來計算費用。
*為了減少記錄數,不按照每天一計算,按照一段時間計算的方式求解。
*比如:在1號到5號某個公司、服務的人數都是一樣的,那麼記錄一條記錄即可。公司、服務、時間段、*人數
*求解步驟:
*1、求出所有的時間點包括輸入的引數
*2、按照時間點來將一條記錄分割成多條記錄
*3、按照公司、服務、時間段分組、求出費用
*/
WITH
INSERT_TIME--輸入的引數:兩個時間點
AS
(
SELECT TO_DATE(:P_START_DATE,'YYYYMMDD') DATE1,TO_DATE(:P_END_DATE,'YYYYMMDD')+1 DATE2 FROM DUAL
),
ALL_TIME--所有的時間點,包括輸入的兩個時間點
AS
(
SELECT SU.COMPANY_ID,S.SERVICE_ID,S.START_DATE DT1
FROM SERVICE_USAGE S,SERVICE_USERS SU
WHERE S.USER_ID=SU.USER_ID
UNION
SELECT SU.COMPANY_ID,S.SERVICE_ID,S.END_DATE+1
FROM SERVICE_USAGE S,SERVICE_USERS SU
WHERE S.USER_ID=SU.USER_ID
UNION
SELECT C.COMPANY_ID,S.SERVICE_ID,DATE1
FROM INSERT_TIME,COMPANIES C,SERVICES S
UNION
SELECT C.COMPANY_ID,S.SERVICE_ID,DATE2
FROM INSERT_TIME,COMPANIES C,SERVICES S
),
ALL_GROUP--根據所有的時間點,將一條記錄分成多條,根據上邊求出的所有時間段(使用LEAD函式)
AS
(
SELECT SU.COMPANY_ID,S.USER_ID,S.SERVICE_ID,S.START_DATE,S.END_DATE+1 END_DATE,ALT.DT1,
LEAD(DT1,1) OVER(PARTITION BY SU.COMPANY_ID, S.USER_ID, S.SERVICE_ID ORDER BY ALT.DT1 ) DT2
FROM SERVICE_USAGE S,SERVICE_USERS SU,ALL_TIME ALT,INSERT_TIME IT
WHERE S.USER_ID=SU.USER_ID
AND SU.COMPANY_ID=ALT.COMPANY_ID
AND S.SERVICE_ID=ALT.SERVICE_ID
AND S.START_DATE<=ALT.DT1
AND S.END_DATE+1>=ALT.DT1
AND ALT.DT1>=IT.DATE1
AND ALT.DT1<=IT.DATE2
),
GROUP_COM--按照公司、服務、時段分組,求出人數及時間間隔
AS
(
SELECT AA.COMPANY_ID,AA.SERVICE_ID,DT1,DT2,COUNT(1) PEOPLE_NUM,DT2-DT1 DATES
FROM ALL_GROUP AA
WHERE AA.DT2 IS NOT NULL
GROUP BY AA.COMPANY_ID,AA.SERVICE_ID,DT1,DT2
),
BELONG_GROUP--求出屬於哪個歸檔
AS
(
SELECT BB.COMPANY_ID,BB.SERVICE_ID,PEOPLE_NUM,DT1,DT2,DATES,
CASE WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=1 THEN 1 WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=2 THEN 2 WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=3 THEN 3 WHEN PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=4 THEN 4 END LEV
FROM GROUP_COM BB,SERVICE_RATES SR
WHERE BB.COMPANY_ID=SR.COMPANY_ID
AND BB.SERVICE_ID=SR.SERVICE_ID
AND ((PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=1)
OR (PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=2)
OR (PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=3)
OR (PEOPLE_NUM>=SR.USER_COUNT_MIN AND PEOPLE_NUM<=SR.USER_COUNT_MAX AND CATEGORY_ID=4)
)
),
all_money--求出費用
AS
(
SELECT CC.COMPANY_ID,CC.SERVICE_ID,LEV,SUM(DATES*PEOPLE_NUM*SR.RATE) SINGLE_FEE
FROM BELONG_GROUP CC,SERVICE_RATES SR
WHERE CC.COMPANY_ID=SR.COMPANY_ID
AND CC.SERVICE_ID=SR.SERVICE_ID
AND LEV=SR.CATEGORY_ID
GROUP BY CC.COMPANY_ID,CC.SERVICE_ID,LEV
)--行專列
SELECT DD.COMPANY_ID,C.COMPANY_NAME,DD.SERVICE_ID,S.SERVICE_NAME,
MAX(DECODE(LEV,1,SINGLE_FEE)),
MAX(DECODE(LEV,2,SINGLE_FEE)),
MAX(DECODE(LEV,3,SINGLE_FEE)),
MAX(DECODE(LEV,4,SINGLE_FEE)),
SUM(SINGLE_FEE)
FROM all_money DD,COMPANIES C,SERVICES S
WHERE DD.COMPANY_ID=C.COMPANY_ID
AND DD.SERVICE_ID=S.SERVICE_ID
GROUP BY DD.COMPANY_ID,C.COMPANY_NAME,DD.SERVICE_ID,S.SERVICE_NAME
ORDER BY DD.COMPANY_ID,C.COMPANY_NAME,DD.SERVICE_ID,S.SERVICE_NAME;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25323853/viewspace-692487/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OpenHarmony創新賽|賦能直播第四期
- [SWPUCTF 2021 新生賽]easy_sqlSQL
- 核心實戰教程第四期 _ 帶你走進資料庫 SQL 引擎資料庫SQL
- 積木大賽
- 【CSDN競賽第四期】贏榮譽證書和CSDN周邊等精美禮品
- 第十五屆藍橋杯大賽軟體賽省賽 C/C++ 大學 A 組C++
- GeekPwn雲安全挑戰賽賽前大揭秘!
- 大賽報名 | AI口罩佩戴檢測大賽期待你的參與!AI
- 程式設計大賽WBS程式設計
- 第二屆資料安全大賽“數信杯”資料安全大賽 WP
- 智慧航空AI大賽-阿里雲演算法大賽總結(原始碼分享)AI阿里演算法原始碼
- 2022廣東大學生攻防大賽WP
- 2024廣東大學生攻防大賽WP
- DBASK問答集萃第四期
- 賽程更新| 2022微軟與英特爾黑客鬆大賽火熱報名中,兩大賽道等你Battle!微軟黑客BAT
- Datawhale AI夏令營-第四期(AIGC方向)-Task01-可圖Kolors-LoRA風格故事挑戰賽AIGC
- 《安全大咖》第四期 | 專訪“中國網際網路之父”許榕生
- 2020軟體創新大賽
- NEO技術文章徵集大賽
- 全國大學生資訊保安競賽初賽writeup
- 2021數字中國創新大賽大資料賽道—城市管理大資料專題落幕大資料
- 全國首屆大模型創新創意應用大賽開啟,等你來賽!大模型
- 中國大學生數學競賽(非數學專業類)競賽大綱
- 第十五屆浙江大學寧波理工學院程式設計大賽(同步賽)程式設計
- 動感地帶5G電競大賽新疆賽區火熱開賽
- 【比賽覆盤】2024第七屆“傳智杯”全國大學生計算機大賽程式設計挑戰賽(初賽第一場)計算機程式設計
- 賽況激烈!2022 OceanBase資料庫大賽50強誕生資料庫
- 2020 年百度之星程式設計大賽 - 初賽三程式設計
- 2020年百度之星程式設計大賽-初賽二程式設計
- 2020年lfyz演算法設計大賽賽後題解演算法
- 第十四屆藍橋杯大賽軟體賽省賽Python 《三國遊戲》Python遊戲
- 競賽釋出 | AI戰疫·小分子成藥屬性預測大賽開賽!AI
- 幽默:程式設計師吹牛大賽程式設計師
- 極客大賽的碎碎念
- 藍橋杯大賽——驅動程式
- 大資料競賽技術分享大資料
- sql大資料 基礎(檢視)SQL大資料
- 大資料 SQL Boy 脫坑指南大資料SQL
- 碼力無限,助力大賽!2021 OceanBase 資料庫大賽專屬鍵盤等你來拿!資料庫