Почему оператор 'where', кажется, фильтрует ожидаемые строки в SAS pro c SQL? - PullRequest
0 голосов
/ 22 апреля 2020

Сначала я присоединился к двум таблицам, а затем присоединился к третьей таблице, теперь в результате я получил еще 1000 строк. Но когда я добавил оператор where после процесса соединения, я могу получить только 200 строк, и кажется, что некоторые ожидаемые строки были отфильтрованы. Я не знаю, что я сделал не так.

proc sql;
    create table ECG.RECON as 
    select a.SUBJID as SUBJID_004 , 
        a.VISIT as VISIT_004, 
        input(a.EGDAT, yymmdd10.) as EGDAT_004 , 
        ...
        b.SUBJID as SUBJID_001 , 
        ...
        c.DSDECOD 
    from 
    SOURCE.A a full join SOURCE.B b on 
            (a.SUBJID = b.SUBJID and a.VISIT = b.VISIT )
    full join SOURCE.C as c on b.SUBJID = c.SUBJID
    where c.EPOCH = "SCR" and c.DSDECOD ne "FAILURE" and a.TEST = "Inter";
quit;


1 Ответ

1 голос
/ 22 апреля 2020

Ваше предложение where вызывает фильтрацию пустых строк. Рассмотрим упрощенную схему:

Таблица A

Col1    Col2
----------------
1        A
2        B

Таблица B

Col1    Col2
----------------
1        X
3        Y

И простое полное соединение без фильтр:

SELECT  *
FROM    TableA AS A
        FULL JOIN TableB AS B
            ON A.Col1 = B.Col1

который вернет

A.Col1   A.Col2     B.Col1    B.Col2
---------------------------------------
1        A          1           X
2        B          NULL        NULL
NULL    NULL        3           Y

Теперь, если вы примените фильтр к чему-либо из A, например, WHERE A.Col1 = 1, вы избавитесь от 2-й строки ( вероятно, как и предполагалось), начиная с 2 <> 1, но вы также удалите 3-ю строку, поскольку A.Col - это NULL и NULL <> 1. Поскольку вы удалили все строки без соответствующей записи в TableA, вы фактически превратили свое полное соединение в левое соединение. Если вы затем примените дополнительный предикат к TableB, ваше левое соединение станет внутренним соединением.

С Полными объединениями я считаю, что самое простое решение - применить ваши фильтры перед объединением, используя подзапросы, например:

SELECT  *
FROM    (SELECT * FROM TableA WHERE Col1 = 1) AS A
        FULL JOIN TableB AS B
            ON A.Col1 = B.Col1;

, который удаляет 2-ю строку, но все еще сохраняет 3-ю строку из предыдущих результатов:

A.Col1   A.Col2     B.Col1    B.Col2
---------------------------------------
1        A          1           X
NULL    NULL        3           Y

Вы также можете использовать OR, но чем больше у вас предикатов, тем более запутанным может быть, например,

SELECT  *
FROM    TableA AS A
        FULL JOIN TableB AS B
            ON A.Col1 = B.Col1
WHERE   (Col1 = 1 OR A.Col1 IS NULL);
...