2016-07-07 18 views
0

を持つすべてのレコードを取得するレコードをループするPL/SQLスクリプト:私は、これらの条件に基づいて、国の数を生成するPL/SQLスクリプトを作成しようとしています条件

  • 自然滞在の旅の
    • もっと
    • 少ない月1より

      enter image description here

      :最終的な目標は、(/ 1国1年)は、このような何かを得ることです

1週間以上が、1ヶ月未満1週間

  • より

    私は単一のSQL文を手動で生成する方法を試みましたが、のPL/SQLループを使用して実行する方法がわかりません。誰かが私にどのように見せてもらえるかどうか感謝します。

    以下は、関連データベースのテーブル構造です。

    enter image description here

    enter image description here

    enter image description here

    任意の助けをありがとう!

  • +0

    あなたがデータベースを作成するためのスクリプトのようないくつかのサンプルデータ(pastebin.com上FE)を提供することができます:各行について、あなたはカウントがゼロであっても、全旅行タイプと期間のカウントを取得しますいくつかのデータがありますか?それはPL/SQLなしで行うことができ、あまり時間がかからないでしょう。 –

    答えて

    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; 
    

    出力例:

    SQL

    enter image description here

    PL/SQL

    enter image description here

    +0

    ありがとうMottor ..私は誤って非常に申し訳ありません。私は間違って私のテーブルの列に間違いをしました。TB_TRAVEL_ITINERARYは、TRIP_ID列を持っていて、他の方法ではありません。本当にありがとう、URヘルプ。私はすでにテーブルを更新しました。 = X – user3188291

    +0

    私はそれを変更しました – Mottor

    +0

    あなたは、スクリプトを実行すると、私のサンプル出力を提供することができますか?出力は私が最初のスクリプトを実行することから取得する国の名前の単なるリストです。 :( – user3188291

    0

    ここでの選択肢のカップルだ - それは本当にあなたがデータが返さたいかによって異なります。

    この最初の例は、データに存在する旅行の年、国、性質の組み合わせごとに1つの行を返します。データで、私はそのタイプのない旅が存在しないので、それはオーストラリアの行とWORKを与えることはありません使用しています

    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

    は、この第二の例は、今年のすべての組み合わせごとに1行を返し、データに存在する国

    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

    関連する問題