【问题标题】:SAS SQL: Join and Union in Combination to Fill RowsSAS SQL:联合和联合填充行
【发布时间】:2017-03-14 16:30:32
【问题描述】:

我实际上是在尝试加入两个变量,IDACCOUNTNUMBER。简单。但是,FULL 数据集有一行常见的ID,但不同的ACCOUNTNUMBER(注意重命名)和CAR。我想将这些合并并让ID 保留这些值。请参阅下面的示例数据:

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

DATA SUBSET;
    LENGTH ID ACCOUNTNUMBER $12.;
    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= 语句读取、排序和合并,因为它需要更长的时间。

【问题讨论】:

    标签: sql join merge sas union


    【解决方案1】:

    我想出了一些与您提供的玩具数据一起使用的 SQL 代码,并且似乎给出了您想要的结果。这将执行两个 INNER JOINS - 第一个使用来自“FULL”的 ID,第二个连接使用来自“SUBSET”的 ID - 在两个 INNER JOINS 之间使用 UNION。我认为这段代码效率不高,但我想不出任何其他方法来实现这一点。使用您的数据样本进行测试,看看它是否按您想要的方式工作。

    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;
    

    【讨论】:

      【解决方案2】:

      这很奇怪,因为您想查找car,即使在没有匹配帐号的行上也是如此。

      因此,一种方法是将union 与所有id/accountnumber 对组合在一起以获取所有行。然后将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;
      

      【讨论】:

      • 我认为您混淆了哪些变量在哪些数据集中导致错误。 s.car 不应该是 f.car,因为变量位于 FULL 数据集中?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2013-05-20
      • 2014-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多