计算SQL中链的长度

时间:2017-04-05 12:44:18

标签: sql sas chain

我在SAS / SQL中有一个表,如下所示:

输入

Field1  Field2
A       B
E       F
C       D
B       C

我想要第三列告诉我可以用Field1和Field2制作的“链”的长度。我将用一个例子来解释。在我们的例子中,我想要:

输出

Field1 Field2 Length
A      B      1
B      C      2
C      D      3
E      F      1

这样做会找到“链”并计算其长度。在这个例子中,我们将有2个链:“A-B-C-D”和“E-F”。链首先形成一条带有链的起点的链,在这种情况下是“A-B”。然后,因为Field2中的值是B,它将在Field1中查找值B并将其写入第一行,并使用新的对应值Field2,在本例中为“B-C”。然后它会检查Field1中是否存在值C,如果是这种情况则将其写下来。在我们的例子中,它将是“C-D”。同样,它将检查Field1中是否存在值D.因为它不存在,所以它将使用以下链开始算法,并且会写出没有更多连接的“E-F”。

长度值将给出该对的“深度”。 “A-B”是第一对,“B-C”是第二对链“A-B-C”,“C-D”是第三对链“A-B-C-D”。

我无法找到解决方案,有任何帮助来实现这一目标吗?它不需要完全采用这种形式,任何变通方法都会有很大的帮助。

如果重要的话,对于给定的行,从不是Field1 = Field2的情况。

谢谢!

1 个答案:

答案 0 :(得分:0)

在SAS的SQL实现中不可能。

在数据步骤中有很多方法可以做到这一点。如果您了解哈希值,哈希对象可能是最简单的。使用哈希迭代器从哈希中获取第一行,然后获取与field2匹配的任何行;如果没有行匹配field2,请停止查看并让迭代器拉出下一个。

data have;
input Field1 $ Field2  $;
datalines;
A       B
E       F
C       D
B       C
;;;;
run;

data want;
  if 0 then set have;
  declare hash h(dataset:'have', ordered:'a');
  h.defineKey('field1');
  h.defineData('field1','field2');
  h.defineDone();
  declare hiter hi('h');

  do rc = hi.next() by 0 while (rc=0);  *outside iterator - grab the next available row;
    seq = 1;        *initialize the sequence variable;
    output;         *output the first row;
    do rc_h = h.find(key:field2) by 0 while (rc_h=0);  *inside seek - looks for a row (anywhere) that matches field2.;
      seq=seq+1;    *increment the sequence variable;
      output;       *output this row;
      rc_r = h.remove();          *remove that row from the hash as it has been "used";
      rc_h = h.find(key:field2);  *look to see if there is another match in this sequence;
    end;
    rc = hi.next();
  end;
  stop;
  drop rc:;
run;