2015年12月21日 星期一

SAS 的 Data step 與 Proc SQL


文獻1:Malachy J. Foley. "MERGING vs. JOINING: Comparing the DATA Step with SQL" SUGI 30.

圖一


data step merge 
... ...
MERGE  one (IN=in1) two (IN=in2); BY id ;
IF 條件設定;
RUN;




重點摘要:
  • 各個資料檔的主 id 沒有重覆, Match-merge的情況下 data step merge 與 SQL JOIN可以有相同的產出。data step merge  的各種條件設定,與相對應的 SQL JOIN 說明如下:
    ABC區    IF in1 = 1 or in2 = 1;        相當於 SQL 的 FULL OUTER JOIN。
    AB   區    IF in1 = 1                ;        相當於 SQL 的 LEFT OUTER JOIN。
      BC 區    IF                 in2 = 1;        相當於 SQL 的 RIGHT OUTER JOIN。
      B   區    IF in1 = 1 AND  in2 = 1;        相當於 SQL 的 INNER JOIN。

  • SQL JOIN 主要分二類:INNER、OUTER,其執行機制來於 CARTESIAN PRODUCT。 OUTER JOIN 又可分三類 FULL OUTER JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN,在寫程式時, OUTER 這個字可以省略(如 FULL JOIN)。
  • CARTESIAN PRODUCT (圖二)沒有  ON key-field-condition
    基本上如果 one 有3筆,two有2筆,three有2筆,其結果就是 3 * 2 * 2 = 12筆
    以SQL來寫,
    PROC SQL;
      CREATE TABLE allrecord AS
      SELECT *
      FROM one, two, three
    ;
    QUIT;
圖二

  • INNER JOIN的兩種寫法(概念如圖一),有  ON key-field-condition
    PROC SQL;
      CREATE TABLE both AS
      SELECT *
      FROM one INNER JOIN two
      ON one.id = two.id
    QUIT;

    PROC SQL;
      CREATE TABLE both AS
      SELECT *
      FROM one, two
      WHERE one.id = two.id
    QUIT;
  • OUTER JOIN 也是有 ON key-field-condition,主 key 最好要另加上coalesce () ,如:SELECT coalesce (one.id , two.id) AS new_id。
    • 若只要 A 區(有 one但不含 two)
      SQL可用
          LEFT JOIN ... ...
          ON ... ...
          WHERE two.id  IS  NULL
      data step 可用  IF in1 = 1 AND  in2 = 0;

      若只要 C 區(有 two但不含 one)
      SQL可用
          RIGHT JOIN ... ...
          ON ... ...
          WHERE one.id  IS  NULL
      data step 可用  IF in1 = 0 AND  in2 = 1;

      若只要 AC 區(排除 B,即排除one與 two的聯集)
      SQL可用
          FULL OUTER JOIN ... ...
          ON ... ...
          WHERE one.id  IS  NULL OR  two.id  IS  NULL
      data step 可用  IF in1 +  in2 = 1;


文章最後有用 data step 作 CARTESIAN PRODUCT 的範例,如下
DATA CART ;
SET one  (rename=(ID=ID1));
    DO i=1 TO kkk;
        SET two point=i  nobs=kkk;    OUTPUT;
    END;
RUN;

原則上就是分兩次 SET,並且在第2次時,搭配 do-output-end,最重要的還有 point 與 nobs 的指令,我猜似它的用途為
1、nobs 得到 two 有幾筆資料,並匯到 變項 kkk裡,而 kkk剛好告訴 DO loop 何時要停整。
2、point 很重要的,但無解,不懂。

沒有留言: