SAS SQL: объединение и объединение в комбинации для заполнения строк

Я, по сути, пытаюсь объединить две переменные, IDи ACCOUNTNUMBER. Простой. Однако FULLнабор данных имеет ряд общихID, но отличных ACCOUNTNUMBER(обратите внимание на переименование) и CAR. Я хотел бы объединить их и IDсохранить эти значения. См. пример данных ниже:

DATA FULL;
    LENGTH ID ACCT_FULL CAR .;
    INPUT ID $ ACCT_FULL $ CAR $;
    DATALINES;
    A   123 MAZDA
    B   456 FORD
    C   789 CHEVY
    D   777 NISSAN
    ;
RUN;

DATA SUBSET;
    LENGTH ID ACCOUNTNUMBER .;
    INPUT ID $ ACCOUNTNUMBER $;
    DATALINES;
    A   123
    B   456
    C   789
    D   012
    ;
RUN;

** THIS QUERY DOES NOT QUITE OUTPUT A DATASET I WANT **;
PROC SQL NOPRINT;
    CREATE TABLE WANT_BAD AS
    SELECT *
    FROM SUBSET AS A
    LEFT JOIN
    FULL(RENAME=(ACCT_FULL=ACCOUNTNUMBER)) AS B
    ON      A.ID = B.ID AND 
            A.ACCOUNTNUMBER = B.ACCOUNTNUMBER;
QUIT;

Вот параллельное сравнение того, что у меня в настоящее время есть, с тем, что я хочу:

Bad Output:      Want Output:

A   123 MAZDA   |   A   123 MAZDA
B   456 FORD    |   B   456 FORD
C   789 CHEVY   |   C   789 CHEVY
D   012         |   D   012 NISSAN
                |   D   777 NISSAN

Мой вопрос — Могу ли я добавить какой-то UNIONоператор К моему запросу для вывода данных, которые я хочу? Я хотел бы сделать это в SQL, а не в шагах данных, потому что мои FULLданные в реальной жизни массивны, и я не хочу читать, сортировать и объединять с помощью IN=инструкций, потому что это займет гораздо больше времени.

2 ответа

  1. Это странно, потому что вы хотите посмотреть carчетные строки, у которых нет совпадающих номеров счетов.

    Таким образом, один метод состоит в том, чтобы unionобъединить все idaccountnumberпары/, чтобы получить все строки. Затем верните carинформацию:

    proc sql:
        select fs.id, fs.accountnumber, f.car
        from ((select f.id, f.accountnumber from full f) union
              (select s.id, s.acct_full from subset s)
             ) fs left join
             full f
             on f.id = fs.id;
    
  2. Я придумал некоторый SQL-код, который работает с игрушечными данными, которые вы предоставили, и, кажется, дает результат, который вы хотите. Это выполняет два внутренних соединения — первое использует идентификатор из «FULL», а второе соединение использует идентификатор из «SUBSET» — с объединением между двумя внутренними соединениями. Я не думаю, что этот код эффективен, но я не мог придумать никакого другого способа выполнить это. Протестируйте образец данных, чтобы проверить, работает ли он так, как вы хотите.

    PROC SQL NOPRINT;
    
        /* THIS INNER JOIN MATCHES BY ID ONLY */
        /* CREATES NEWACCT USING ACCOUNT NUMBER FROM "FULL" */
        CREATE TABLE TRY_AGAIN AS
    
        SELECT A.*, B.*,  
            B.ACCT_FULL AS NEWACCT
        FROM SUBSET AS A
        INNER JOIN 
        FULL  AS B
        ON A.ID = B.ID 
    
        UNION
    
        /* THIS INNER JOIN MATCHES BY ID AND AND ACCOUNT NUMBER */
        /* KEEPS ONLY IF ACCOUNT NUMBERS DO NOT MATCH */
        /* CREATES NEWACCT USING THE ACCOUNT NUMBER FROM "SUBSET" */
        SELECT A.*, B.*,  
             A.ACCOUNTNUMBER AS NEWACCT 
        FROM SUBSET AS A
        INNER JOIN 
        FULL  AS B
        ON      A.ID = B.ID AND 
                A.ACCOUNTNUMBER NOT= B.ACCT_FULL
    
        ORDER BY ID, NEWACCT
    ;
    
    QUIT;