2010-12-01 9 views
0

カーソルに値のセットがあります。たとえば:empidは、第1の選択(where ISenrolled =1)の両方で表示され、第二(where ISenrolled =2)を選択した場合PL/SQLカーソル一意のレコードを選択し、フラットファイルで印刷

CURSOR c_stock_option IS 
SELECT empid, '1' AS ISenrolled 
FROM employee emp 
UNION ALL 
SELECT empid, '2' AS ISenrolled 
FROM employee emp; 

は今、私が確認したいです。私は最初の選択where enroll=1から値を取得し、where enroll=2を拒否したいだけです。この基準を満たすレコードだけを印刷したいと思う。

FOR v_stock_option_record IN c_stock_option LOOP 
    IF v_esppstock_recs IN (v_stock_option_record.empid) THEN 

    END IF; 
    -- Participant file. 
    v_member_string_1 := v_stock_option_record.empid || G_DELIMITER || --1. participant id 
    v_stock_option_record.last_name || G_DELIMITER || --4. Last Name 
    v_stock_option_record.first_name || G_DELIMITER || --5. First Name 
END loop; 

クエリの最初の部分で、それは(それが株式を購入した従業員のセットのみを与える株式を購入したすべての従業員を選択され、クエリの他の部分は、内のすべてのアクティブな従業員を与えます会社の従業員が選択肢の最初の部分にある従業員は常に選択の第2部分にありますが、選択の第2部分にある従業員は必ずしも第1部分にはありません。私がする必要があるのは、isenrolled = 1の従業員だけを選択することです)。 以下はそれ以外の場合は2 IsEnrolledを返すよ、ここにそれが存在する場合、それだけで1 => IsEnrolledを返します動作するはず一つの方法である

SELECT 
    empid, 
    '1' AS ISenrolled 
    FROM employee emp, 
    hrempusf usf 
    where emp.employee = usf.employee 
      AND usf.field_key = 76 ---- 76 determines that employee has purchased stocks 
UNION ALL 
    SELECT 
    empid, 
    '2' AS ISenrolled 
    FROM employee emp; 
+1

私はあなたのコードをフォーマットしました([推奨](http://meta.stackexchange.com/questions/71252/pl-sql-cursor-select-unique-records-from-cursor-and-print-in-フラットファイルクローズ))、あなたのコードの一部が実際にSQLコメントであることが明らかになりました。それを修正するには「編集」をクリックしてください。 (私は既に最初のクエリの2行目から1つの誤った "AS"を削除しました) – Arjan

+0

@user、あなたは編集してもコードを修正しませんでした...また、SELECT自体は意味をなさない。 – Arjan

+1

クエリから、UNION ALLの両方の部分には常に同じempoyeesが設定されます。正確にあなたが望むものの詳細を与え、より明確な答えを得る。 – Nivas

答えて

0

を区別するSQLです。

「データ」は、2つの選択文を模倣することです。

with data as(
select 1 empId, 1 ISEnrolled from dual 
union 
select 2 empId, 1 ISEnrolled from dual 
union 
select 3 empId, 1 ISEnrolled from dual 
union 
select 4 empId, 1 ISEnrolled from dual 
union 
select 5 empId, 1 ISEnrolled from dual /** these 5 are mimicing your first select */ 
union 
select 1 empId, 2 ISEnrolled from dual /** the next are the 'all' */ 
union 
select 2 empId, 2 ISEnrolled from dual 
union 
select 3 empId, 2 ISEnrolled from dual 
union 
select 4 empId, 2 ISEnrolled from dual 
union 
select 5 empId, 2 ISEnrolled from dual 
union 
select 6 empId, 2 ISEnrolled from dual 
union 
select 7 empId, 2 ISEnrolled from dual 
union 
select 8 empId, 2 ISEnrolled from dual 
union 
select 9 empId, 2 ISEnrolled from dual 
union 
select 10 empId, 2 ISEnrolled from dual) 
, 
onlyOneIsEnrolled as (
    select empId, isEnrolled 
    from data 
    where isEnrolled = 1 
) , 
notInOneIsEnrolled as(
    select empId, isEnrolled 
    from data d 
    where not exists(select null 
          from onlyOneIsEnrolled ooie 
          where ooie.empid = d.empId 
          ) 
) 
select EmpId, isEnrolled 
    from onlyOneIsEnrolled 
    union 
select EmpId, isEnrolled 
    from notInOneIsEnrolled 
order by isEnrolled, EmpId 

これは、タスクを達成するためのひとつの方法である、onlyOneIsEnrolledはすべて1年代を収集し、その後、notInOneIsEnrolledは、上記のすべてのempsないを取得し、クエリの最後の部分は、それらを一緒に置きます。

このタスクを実行するには多くの方法がありますが、CTEを使用しますが、必要に応じてwith句を使用せずにこれを行うことができます。

+0

私はカーソルのやり方をしなければなりません。例えば、CURSOR c_stock_option IS empid、name、ssn、isenrolled = 1の従業員からisenrolledを選択します。CURSOR c_espp_option IS empid、name、ssn、isenrolled = 2の従業員からisenrolledを選択します。カーソル1にある2番目のカーソルのすべてのrecsを拒否したい、どうすればよいのですか – user525552

+0

このソリューションは完璧なおかげです。私のために働いた。 – user525552

1

複雑なPL/SQLは不要ですが、LEFT OUTER JOINが必要です。これにより、HREMPUSFレコードと一致するかどうかにかかわらず、すべてのEMPLOYEEレコードが返されます。最初の引数がnullでない場合、3番目の引数は、それがnullの場合

SELECT 
    empid 
    , nvl2(usf.field_key ,'1', '2') AS ISenrolled 
    FROM employee emp 
    left outer join hrempusf usf 
      on (usf.employee = emp.employee 
       and usf.field_key = 76) 

NVL2()は、第2の値を返します。

関連する問題