之间的PROC SQL上的哈希连接等效项

之间的PROC SQL上的哈希连接等效项,sql,join,hash,sas,between,Sql,Join,Hash,Sas,Between,我通常使用PROC-SQL来表示我加入一个表时的日期条件(即target\u-date介于start\u-date和end\u-date之间) 在考虑内部联接时,我已经能够成功地将其转换为哈希联接: data hash_join; if _n_ = 1 then do; declare hash add1(dataset:'table_2',multidata: 'Y'); add1.defineKey('key_1'); add1.defineData('start_d

我通常使用
PROC-SQL
来表示我加入一个表时的日期条件(即
target\u-date
介于
start\u-date
end\u-date
之间)

在考虑
内部联接时,我已经能够成功地将其转换为哈希联接

data hash_join;
if _n_ = 1 then do;
    declare hash add1(dataset:'table_2',multidata: 'Y');
    add1.defineKey('key_1');
    add1.defineData('start_date','end_date','value_1');
    add1.defineDone();
end;

format 
    start_date date9.
    end_date date9.
    value_1 10.5
;

set table_1 (keep=key_1 target_date);

if add1.find() = 0 then do until (add1.find_next());
    if start_date le target_date le end_date then output;
end;
run;
这与:

proc sql;
create table sql_join as select
b.start_date,
b.end_date,
b.value_1,
a.key_1,
a.target_date
from table_1 a
inner join table_2 b
on  a.key_1 = b.key_1 and
a.target_date between b.start_date and b.end_date
;quit;
但是,我很难弄清楚左连接的等价物是什么。例如,如果某个东西没有加入,我想输出,我认为这很简单:

if add1.find() ne 0 then output;
如果它
JOIN
s并且日期介于之间,那么这似乎也很简单:

if add1.find() = 0 then do until (add1.find_next());
    if start_date le target_date le end_date then output;
end;
但是,如何从表1中获取可能加入但在
开始日期
结束日期
之间没有
目标日期
的其余记录呢?例如,假设
表2
是销售的
开始日期
结束日期
,而对于
键1=“衣服”
,销售直到2月1日才开始。如果我的代码> Table S1 在1月1日有“衣服”和销售,它将在代码上<代码>连接< /代码>,但是我想输出空白值。有什么办法吗


任何帮助都将不胜感激

我想你只需要跟踪某个东西是否有钥匙,但不在范围内:

if add1.find() ^=0 then output;
else do;
   found = 0;
   do until (add1.find_next());
       if start_date le target_date le end_date then do;
          output;
          found=1;
       end;
   end;
   if ^found then output;
end;

没有数据可供测试,所以这只是我在so中编写的代码。如果它不起作用,请告诉我。

您只需跟踪是否找到匹配项即可。由于您没有使用hash find来跟踪事物的“中间”部分,因此您不能使用它,所以您只需自己完成

看看这个例子。在这里,我修改了SASHELP.CLASS,使其看起来像您的输入表,然后添加一些逻辑以查看是否找到了任何内容

data table_1;
  set sashelp.class;
  rename age=target_date name=key_1;
  drop height weight;
run;

data table_2;
  set sashelp.class;
  do _i = 1 to mod(_n_,3);
    start_date = age-3+_i;
    end_date = age+1-_i;
    if start_date le end_date then output;
  end;
  rename name=key_1 height=value_1;
  keep height weight start_date age end_date name;
run;

data hash_join;
if _n_ = 1 then do;
    declare hash add1(dataset:'table_2',multidata: 'Y');
    add1.defineKey('key_1');
    add1.defineData('start_date','end_date','value_1');
    add1.defineDone();
end;

format 
    start_date date9.
    end_date date9.
    value_1 10.5
;

set table_1 (keep=key_1 target_date);

if add1.find() = 0 then do until (add1.find_next());
    if start_date le target_date le end_date then do;
      found=1;
      output;
    end;
end;
call missing(of value_1);  *full list of values to clear - all of hash data elements;
if not (found) then output;
run;

就像我的孩子们会说的,“厄运”哈哈。是的,非常令人印象深刻的相似代码,因为我们分别做了它们。。。和fwiw,将你的粘贴到我的上面,但使用我的样本数据是正确的。实际上,它不是100%工作…它肯定包括那些没有连接的,但它为它输入了错误的值(即日期和值不匹配的目标日期),而不是包含所有空格的记录。澄清一下:它是从表_1返回初始值,并返回find=。但是,它也会从输出中的表2中返回最后一个值\u 1、开始日期和结束日期值。sofound=,但返回的值不正确<代码>调用丢失(值为_1)在最后一个输出行之前。