PL / SQL游标选择唯一记录并在平面文件中打印

时间:2010-12-01 14:45:38

标签: oracle plsql

我在游标中设置了一组值。例如:

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

现在,我想检查empid是否同时出现在第一个选择(where ISenrolled =1)和第二个选择(where ISenrolled =2)中。我只希望从首先选择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;

在查询的第一部分,它选择购买股票的所有员工(只给出已购买股票的一组员工,查询的其他部分给出公司中所有活跃的员工,所以选择的第一部分中的员工将始终位于选择的第二部分,但是选择的第二部分中的员工不一定是第一部分。在员工出现在两个部分的情况下,我需要做的只是选择已登记= 1的员工。 下面是要区分的SQL

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;

2 个答案:

答案 0 :(得分:1)

你不需要复杂的PL / SQL,你只需要一个LEFT OUTER JOIN。这将返回所有EMPLOYEE记录,无论它是否与HREMPUSF记录匹配。

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 )

如果第一个参数不为null,NVL2()将返回第二个值,如果为null,则返回第三个参数。

答案 1 :(得分:0)

以下是一种应该有效的方法,如果它存在,它只返回1 => IsEnrolled,否则它将返回2 IsEnrolled

“数据”是模仿你的两个选择语句。

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子句的情况下执行此操作。