我想創建一個PL/SQL腳本基於這些條件的國家產生的數量:PL/SQL腳本,通過記錄循環得到的所有記錄與條件
- 國家
- 自然旅行
- 年
- 入住天數
- 1個多月
- 減超過1周
- 1周以上,但不到1個月
的最終目標是讓這樣的事情(1年/ 1國):
我試圖通過手動方式(需要很長時間)生成單個SQL語句,但我不確定如何通過PL/SQL循環執行此操作。欣賞是否有人能告訴我如何。
下面是我的數據庫中的相關字段的表結構。
感謝您的幫助!
我想創建一個PL/SQL腳本基於這些條件的國家產生的數量:PL/SQL腳本,通過記錄循環得到的所有記錄與條件
的最終目標是讓這樣的事情(1年/ 1國):
我試圖通過手動方式(需要很長時間)生成單個SQL語句,但我不確定如何通過PL/SQL循環執行此操作。欣賞是否有人能告訴我如何。
下面是我的數據庫中的相關字段的表結構。
感謝您的幫助!
SQL
select c.country_name as country,
a.nature_of_travel,
case d.rn
when 1 then 'More than 1 month'
when 2 then 'Less than 1 week'
else 'Between 1 week and 1 month'
end length_of_stay,
count(*) number_of_trips,
to_char(b.from_date,'YYYY') year
from TB_TRAVELITINERARY b
join TB_TRIP a on a.trip_id=b.trip_id
join TB_COUNTRY c on b.country_code= c.country_code
join (select rownum rn from dual connect by level < 4) d on
case when add_months(b.from_date,1) < b.to_date then 1
when b.from_date+7 > b.to_date then 2
else 3
end = d.rn
group by c.country_name,
a.nature_of_travel,
case d.rn
when 1 then 'More than 1 month'
when 2 then 'Less than 1 week'
else 'Between 1 week and 1 month'
end,
to_char(b.from_date,'YYYY')
PL/SQL
DECLARE
TYPE array_t IS VARRAY (3) OF VARCHAR2 (30);
notarr array_t := array_t ('More than 1 month', 'Less than 1 week','Between 1 week and 1 month');
BEGIN
FOR c1 IN ( SELECT country_name, nature_of_travel,
CASE WHEN ADD_MONTHS (from_date, 1) < TO_DATE THEN 1
WHEN from_date + 7 > TO_DATE THEN 2
ELSE 3
END los,
to_char (from_date,'YYYY') yr,
COUNT (*) cnt
FROM tb_travelitinerary a
JOIN tb_trip b ON a.trip_id = b.trip_id
JOIN tb_country c ON a.country_code = c.country_code
GROUP BY country_name, nature_of_travel, CASE WHEN ADD_MONTHS (from_date, 1) > TO_DATE THEN 1 WHEN from_date + 7 < TO_DATE THEN 2 ELSE 3 END, to_char (from_date,'YYYY')
ORDER BY 4, 1, 2, 3)
LOOP
DBMS_OUTPUT.PUT_LINE(rpad(c1.COUNTRY_NAME,30)||' '||rpad(c1.NATURE_OF_TRAVEL,8)||' '||rpad(notarr(c1.LOS),27)
||' '||to_char(c1.cnt,'999999990')||' '||c1.yr);
END LOOP;
END;
示例輸出:
SQL
PL/SQL
謝謝Mottor ..我太如此如此抱歉..我不小心在我的表列上發生了錯誤。TB_TRAVEL_ITINERARY應該有列TRIP_ID而不是其他方式..這就是爲什麼不管我如何嘗試我們的代碼它不工作。真的很感謝你的幫助,雖然..我已經更新了表格。 = X – user3188291
我改變了它 – Mottor
您好mottor,當您運行ur腳本時能夠提供我的示例輸出嗎?我從運行你的第一個腳本得到的輸出只是一個國家名稱列表。 :( – user3188291
這裏有幾個選擇 - 它取決於您希望如何返回數據。
第一個示例將針對數據中存在的每個旅行年份,國家和性質組合返回一行。隨着數據我已經用它不會給澳大利亞一個行和工作,因爲沒有這種類型的車次:
WITH
tb_country AS
(SELECT 'ABW' country_code, 'Aruba' country_name FROM dual UNION ALL
SELECT 'AFG', 'Afghanistan' FROM dual UNION ALL
SELECT 'AGO', 'Angola' FROM dual UNION ALL
SELECT 'AUS', 'Australia' FROM dual
)
,tb_travleItinerary AS
(SELECT 1 itinerary_id, 1 trip_id, 'AUS' country_code, TO_DATE('19/05/2016','DD/MM/YYYY') date_from, TO_DATE('30/05/2016','DD/MM/YYYY') date_to FROM dual UNION ALL
SELECT 2, 3, 'AFG', TO_DATE('10/01/2016','DD/MM/YYYY'), TO_DATE('13/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 3, 2, 'AFG', TO_DATE('10/02/2016','DD/MM/YYYY'), TO_DATE('01/06/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 4, 5, 'AFG', TO_DATE('10/03/2016','DD/MM/YYYY'), TO_DATE('13/03/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 5, 7, 'AFG', TO_DATE('01/01/2016','DD/MM/YYYY'), TO_DATE('03/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 6, 4, 'AFG', TO_DATE('01/10/2016','DD/MM/YYYY'), TO_DATE('29/10/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 7, 6, 'AFG', TO_DATE('12/01/2016','DD/MM/YYYY'), TO_DATE('11/05/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 8, 8, 'AFG', TO_DATE('15/01/2016','DD/MM/YYYY'), TO_DATE('18/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 9, 9, 'AFG', TO_DATE('22/01/2016','DD/MM/YYYY'), TO_DATE('13/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 10, 10, 'AFG', TO_DATE('31/01/2016','DD/MM/YYYY'), TO_DATE('18/02/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 11, 11, 'AFG', TO_DATE('02/02/2016','DD/MM/YYYY'), TO_DATE('13/10/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 12, 12, 'AFG', TO_DATE('10/02/2016','DD/MM/YYYY'), TO_DATE('11/02/2016','DD/MM/YYYY') FROM dual
)
,tb_trip AS
(SELECT 1 trip_id, 'HOLIDAY' nature_of_travel FROM dual UNION ALL
SELECT 2, 'STUDY' FROM dual UNION ALL
SELECT 3, 'WORK' FROM dual UNION ALL
SELECT 4, 'HOLIDAY' FROM dual UNION ALL
SELECT 5, 'STUDY' FROM dual UNION ALL
SELECT 6, 'WORK' FROM dual UNION ALL
SELECT 7, 'HOLIDAY' FROM dual UNION ALL
SELECT 8, 'STUDY' FROM dual UNION ALL
SELECT 9, 'WORK' FROM dual UNION ALL
SELECT 10, 'HOLIDAY' FROM dual UNION ALL
SELECT 11, 'STUDY' FROM dual UNION ALL
SELECT 12, 'WORK' FROM dual
)
SELECT
country_name
,nature_of_travel
--,length_of_stay
,year
,SUM(less_than_one_week) count_less_than_one_week
,SUM(more_than_one_month) count_more_than_one_month
,SUM(other_duration) count_other_duration
FROM
(SELECT
c.country_name
,t.nature_of_travel
,CASE
WHEN ti.date_to - ti.date_from < 7
THEN 'Less than 1 week'
WHEN ti.date_to - ti.date_from > 30 --note : you need to dfine what you mean by a month
THEN 'More than 1 month'
ELSE 'Between 1 week and 1 month'
END length_of_stay
,CASE
WHEN ti.date_to - ti.date_from < 7
THEN 1
ELSE 0
END less_than_one_week
,CASE
WHEN ti.date_to - ti.date_from > 30
THEN 1
ELSE 0
END more_than_one_month
,CASE
WHEN ti.date_to - ti.date_from BETWEEN 7 AND 30
THEN 1
ELSE 0
END other_duration
,TO_CHAR(ti.date_from,'YYYY') year
FROM
tb_country c
,tb_travleItinerary ti
,tb_trip t
WHERE 1=1
AND c.country_code = ti.country_code
AND ti.trip_id = t.trip_id
) raw_data
WHERE 1=1
GROUP BY
country_name
,nature_of_travel
,year
ORDER BY
country_name
,nature_of_travel
,year
;
第二個例子將返回一行對一年中的每組合數據中存在的國家/地區。對於每一行,你會得到所有旅行類型和持續時間的計數,即使計數爲零:
WITH
tb_country AS
(SELECT 'ABW' country_code, 'Aruba' country_name FROM dual UNION ALL
SELECT 'AFG', 'Afghanistan' FROM dual UNION ALL
SELECT 'AGO', 'Angola' FROM dual UNION ALL
SELECT 'AUS', 'Australia' FROM dual
)
,tb_travleItinerary AS
(SELECT 1 itinerary_id, 1 trip_id, 'AUS' country_code, TO_DATE('19/05/2016','DD/MM/YYYY') date_from, TO_DATE('30/05/2016','DD/MM/YYYY') date_to FROM dual UNION ALL
SELECT 2, 3, 'AFG', TO_DATE('10/01/2016','DD/MM/YYYY'), TO_DATE('13/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 3, 2, 'AFG', TO_DATE('10/02/2016','DD/MM/YYYY'), TO_DATE('01/06/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 4, 5, 'AFG', TO_DATE('10/03/2016','DD/MM/YYYY'), TO_DATE('13/03/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 5, 7, 'AFG', TO_DATE('01/01/2016','DD/MM/YYYY'), TO_DATE('03/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 6, 4, 'AFG', TO_DATE('01/10/2016','DD/MM/YYYY'), TO_DATE('29/10/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 7, 6, 'AFG', TO_DATE('12/01/2016','DD/MM/YYYY'), TO_DATE('11/05/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 8, 8, 'AFG', TO_DATE('15/01/2016','DD/MM/YYYY'), TO_DATE('18/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 9, 9, 'AFG', TO_DATE('22/01/2016','DD/MM/YYYY'), TO_DATE('13/01/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 10, 10, 'AFG', TO_DATE('31/01/2016','DD/MM/YYYY'), TO_DATE('18/02/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 11, 11, 'AFG', TO_DATE('02/02/2016','DD/MM/YYYY'), TO_DATE('13/10/2016','DD/MM/YYYY') FROM dual UNION ALL
SELECT 12, 12, 'AFG', TO_DATE('10/02/2016','DD/MM/YYYY'), TO_DATE('11/02/2016','DD/MM/YYYY') FROM dual
)
,tb_trip AS
(SELECT 1 trip_id, 'HOLIDAY' nature_of_travel FROM dual UNION ALL
SELECT 2, 'STUDY' FROM dual UNION ALL
SELECT 3, 'WORK' FROM dual UNION ALL
SELECT 4, 'HOLIDAY' FROM dual UNION ALL
SELECT 5, 'STUDY' FROM dual UNION ALL
SELECT 6, 'WORK' FROM dual UNION ALL
SELECT 7, 'HOLIDAY' FROM dual UNION ALL
SELECT 8, 'STUDY' FROM dual UNION ALL
SELECT 9, 'WORK' FROM dual UNION ALL
SELECT 10, 'HOLIDAY' FROM dual UNION ALL
SELECT 11, 'STUDY' FROM dual UNION ALL
SELECT 12, 'WORK' FROM dual
)
SELECT
country_name
,year
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'HOLIDAY'
AND ti2.date_to - ti2.date_from < 7
) holiday_lt_1_week
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'HOLIDAY'
AND ti2.date_to - ti2.date_from > 30
) holiday_gt_1_month
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'HOLIDAY'
AND ti2.date_to - ti2.date_from BETWEEN 7 AND 30
) holiday_other
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'WORK'
AND ti2.date_to - ti2.date_from < 7
) work_lt_1_week
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'WORK'
AND ti2.date_to - ti2.date_from > 30
) work_gt_1_month
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'WORK'
AND ti2.date_to - ti2.date_from BETWEEN 7 AND 30
) work_other
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'STUDY'
AND ti2.date_to - ti2.date_from < 7
) study_lt_1_week
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'STUDY'
AND ti2.date_to - ti2.date_from > 30
) study_gt_1_month
,(SELECT count(*)
FROM tb_travleItinerary ti2, tb_trip tt
WHERE ti2.country_code = raw_data.country_code
AND TO_CHAR(ti2.date_from,'YYYY') = raw_data.year
AND ti2.trip_id = tt.trip_id
AND tt.nature_of_travel = 'STUDY'
AND ti2.date_to - ti2.date_from BETWEEN 7 AND 30
) study_other
FROM
(SELECT DISTINCT
c.country_name
,c.country_code
,TO_CHAR(ti.date_from,'YYYY') year
FROM
tb_country c
,tb_travleItinerary ti
WHERE 1=1
AND c.country_code = ti.country_code
) raw_data
WHERE 1=1
你能提供一些示例數據(FE在pastebin.com)像腳本來創建數據庫有一些數據?它可以在沒有PL/SQL的情況下完成,並且不需要太多時間。 –