두 개의 테이블(첫 번째 테이블의 모든 데이터와 두 번째 테이블의 부족한 데이터 포함)을 통합하는 가장 효과적인 방법

질문:

나는 두 개의 표를 가지고 있는데 하나는 사용자가 선택한 정책을 포함하고 다른 하나는 모든 정책을 포함한다.
-- Policies selected by client
create table client_policies (
  id number,
  client_id number,
  policy_id varchar2(30),
  policy_description varchar2(100),
  policy_added_date timestamp,
  policy_modified_date timestamp
)
/

-- All available policies
create table policies (
  policy_id varchar2(30),
  policy_description varchar2(100)
)
/
샘플 데이터:
insert into client_policies values (1, 123, 'HOUSE_INSURANCE', 'house insurance policy', sysdate - 10, sysdate - 3);
insert into client_policies values (2, 123, 'HEALTH_INSURANCE', 'health insurance policy', sysdate - 20, sysdate - 5);
insert into client_policies values (3, 123, 'CIVIL_LIABILITY_INSURANCE', 'civil liability insurance policy', sysdate - 2, sysdate - 1);

insert into policies values ('HOUSE_INSURANCE', 'house insurance policy');
insert into policies values ('HEALTH_INSURANCE', 'health insurance policy');
insert into policies values ('CIVIL_LIABILITY_INSURANCE', 'civil liability insurance policy');
insert into policies values ('CAR_INSURANCE', 'car insurance policy');
insert into policies values ('ETC_INSURANCE', 'etc... insurance policy');
두 가지 시나리오가 있습니다.
  • 사용자가 현재 선택한 정책만 볼 수 있음
  • 현재 선택한 정책과 선택하지 않은 다른 모든 정책을 볼 수 있음
  • 나는 필요한 출력을 만들 수 있는 커서가 하나 있지만, 성능에 대한 지원이 부족하다.나의 문제는 어떻게 이 문제를 개선할 것인가, 아니면 다른 더 좋은 해결 방안이 있습니까?
    declare
      cursor c_get_client_policies(CP_CLIENT_ID            in number,
                                   CP_GET_DEFAULT_POLICIES in varchar2) is
        with policies_data as
         (select 1 rank,
                 id,
                 policy_id,
                 policy_description,
                 policy_added_date,
                 policy_modified_date
            from client_policies cp
           where client_Id = CP_CLIENT_ID
          union
          select 2                  rank,
                 null               id,
                 policy_id,
                 policy_description,
                 null               policy_added_date,
                 null               policy_modified_date
            from policies p
           where CP_GET_DEFAULT_POLICIES = 'Y'),
        ranked as
         (select row_number() over(partition by policy_id order by rank) row_no,
                 pd.*
            from policies_data pd)
        select id,
               policy_id,
               policy_description,
               policy_added_date,
               policy_modified_date
          from ranked
         where row_no = 1
         order by id;
    begin
      for r in c_get_client_policies(123, 'Y') loop
        dbms_output.put_line('ID=' || r.id || ', POLICY_ID=' || r.POLICY_ID ||
                             ', POLICY_DESCRIPTION=' || r.policy_description ||
                             ', POLICY_ADDED_DATE=' || r.POLICY_ADDED_DATE ||
                             ', POLICY_MODIFIED_DATE=' ||
                             r.POLICY_MODIFIED_DATE);
      end loop;
    end;
    /
    
    예상 산출:
    신분증
    정책 표식
    정책 설명
    정책 추가 날짜
    정책 수정 날짜
    1
    주택 보험
    주택 보험증서
    2021.06.11 18:27:02,000000
    2021.06.18 18:27:02,000000
    2
    건강 보험
    건강 보험증서
    2021.06.01 18:27:02,000000
    2021.06.16 18:27:02,000000

    민사 책임 보험
    민사 책임 보험증서
    2021.06.19 18:27:02,000000
    자동차 보험
    자동차 보험증서
    ETC 보험
    기다리다보험증서

    답안

    똑바른 왼쪽 연결이 당신이 묘사한 것과 완전히 일치하는 것 같습니까?
    https://dbfiddle.uk/?rdbms=oracle_18&fiddle=032e5e5f0a1856636f2ba144fd9eb390
    SELECT
      client_policies.id,
      policies.policy_id,
      COALESCE(client_policies.policy_description, policies.policy_description)  AS policy_description,
      client_policies.policy_added_date,
      client_policies.policy_modified_date  
    FROM
      policies
    LEFT JOIN
      client_policies
        ON  client_policies.policy_id = policies.policy_id
        AND client_policies.client_Id = CP_CLIENT_ID
    WHERE
         client_policies.policy_id IS NOT NULL
      OR CP_GET_DEFAULT_POLICIES = 'Y'