2016-07-07 9 views
0

Ich versuche, ein PL/SQL-Skript zu erstellen Anzahl der in einem Land auf der Grundlage dieser Bedingungen zu generieren:PL/SQL-Skript durch die Datensätze in einer Schleife, um alle Datensätze mit Zustand zu erhalten

  • Land
  • Natur Reise
  • Jahr
  • Dauer
    • über 1 Monat
    • Weniger als 1 Woche
    • mehr als 1 Woche, aber weniger als 1 Monat

Das Endziel ist, so etwas zu bekommen (für 1 Jahr/1 Land):

enter image description here

Ich habe versucht, den manuellen Weg (dauert mich eine lange Zeit) der Generierung einzelner SQL-Anweisungen, aber ich bin mir nicht sicher, wie es über eine PL/SQL-Schleife zu tun. Schätze, wenn mir jemand zeigen kann, wie.

Unten ist die Tabellenstruktur in meiner Datenbank mit den relevanten Feldern.

enter image description here

enter image description here

enter image description here

Vielen Dank für jede Hilfe!

+0

Könnten Sie einige Beispieldaten (zB auf pastebin.com) wie Skripte erstellen Datenbanken mit einigen Daten? Es könnte ohne PL/SQL gemacht werden und es würde nicht so viel Zeit brauchen. –

Antwort

0

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; 

Beispielausgabe:

SQL

enter image description here

PL/SQL

enter image description here

+0

Danke Mottor .. Im so so so leid ... ich habe versehentlich einen Fehler auf meinen Tabellenspalten gemacht .. TB_TRAVEL_ITINERARY sollte die Spalte TRIP_ID haben und nicht umgekehrt. Das ist der Grund, egal wie ich den Code versuche, es funktioniert nicht. Wirklich schätzen Sie Ihre Hilfe aber .. Ich habe die Tabellen bereits aktualisiert. = X – user3188291

+0

Ich habe es geändert – Mottor

+0

Hallo Mottor, können Sie mir eine Beispielausgabe zur Verfügung stellen, wenn Sie Ihr Skript ausführen? Die Ausgabe, die ich vom Ausführen deines ersten Skripts bekomme, ist nur eine Liste von Ländernamen. :( – user3188291

0

Hier ein paar Alternativen - es hängt wirklich davon ab, wie Sie die Daten zurückgegeben werden sollen.

Dieses erste Beispiel gibt eine Zeile für jede Kombination von Jahr, Land und Art der Reise zurück, die in den Daten vorhanden ist. Mit den Daten habe ich verwende Es wird nicht eine Zeile für Australien und WORK geben, weil es keine Fahrten dieser Art:

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 
; 

enter image description here

Dieses zweite Beispiel einer Zeile für jede Kombination von Jahr zurück und Land, das in den Daten existiert.Für jede Zeile werden Sie zählt aller Reisearten und Dauern, auch wenn die Zählungen sind Null:

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 

enter image description here