尝试生成唯一的ID,该ID既不是整数,也不是纯文本中的其他值

时间:2019-06-03 16:57:42

标签: sql sas

我正在帮助一位被要求为要输入的两组不同数据生成密钥ID的同事。我已经完成了此步骤,但它对用户的操作不是很友好,因此我正在寻找有关如何制作数据的建议它更具可读性。每个组都有自己的ID,该ID似乎是一个十六进制值。它们的串联似乎是其自身的唯一键。 在这种情况下,将家庭表和帐户表放在一起,并要求她以家庭帐户值生成(一个家庭可以有多个帐户,一个帐户可以涵盖多个家庭)。

我们的数据存储在SQL Server上,但是我们大部分使用SAS进行操作,因此下面使用PROC SQL。

我最初的想法是,最明显的键是同时运行两个键字段并使用定界符。您会在代码的顶部看到这一点。但是,这需要很长的时间,所以我被要求缩短它。我的第二个想法,也是他们最初的要求,是做一个整数字段。您可以通过Monotonic看到它,但是他们感到,由于它在Internet上有关于它的警告,因此他们不信任它。我的第三个想法是通过某种单向函数来运行现有的,连接的字段,但是当我这样做时(请参见下面的MD5),我得到的东西看起来像是侧翼接管了。

/*  creating a table of just the "key" columns */
PROC SQL;
    CREATE TABLE work.ConcatonatedKey AS
        SELECT DISTINCT 
           CATX("G", HouseholdKey,FinancialKey) as Concatonated
        FROM work.OriginalData
    ;
QUIT;

/*  Populate HHFinancialKey */
/* Monotonic documentation */
/*  http://support.sas.com/techsup/notes/v8/15/138.html  */
PROC SQL;
    CREATE TABLE work.ContrivedKeys AS
        SELECT 
              Monotonic() AS HHFinID
            , Concatonated
            , MD5(Concatonated) As foo
        FROM work.ConcatonatedKey
    ;
QUIT;

因此,这里的真正问题是,如果您拥有可以唯一地标识一行但想要使用SAS使其对用户更友好的东西,您将如何处理。 ?

2 个答案:

答案 0 :(得分:2)

SAS UUIDGEN函数可以返回人类可读的字符串或更密集的二进制字符串。每个文档:

  

UUIDGEN函数为每个单元格返回一个UUID(唯一值)。默认结果是36个字符长,如下所示:

     

5ab6fa40-426b-4375-bb22-2d0291f43319。

     

二进制结果长16个字节。

示例:

select
  ... 
  uuidgen() as myGroupId length=36
...

答案 1 :(得分:1)

MD5可能是最简单的解决方案。结果是MD5函数返回一个16字节的字符串,但要使其易于阅读,您可以使用$hex32.格式对其进行格式化。它也非常快且得到广泛支持。

data _null_;
  x = put(md5("some_string_here"),$hex32.);
  put x;
run;

结果:

BB28824D60AE6706F812CC940CAAAF1B

请注意md5()区分大小写和前导/后跟空格。因此,您可能希望/需要对所有内容进行大写修改,并在通过函数运行它之前修剪空间以在不同平台上获得一致的结果。

发生碰撞的危险接近于零:

How many random elements before MD5 produces collisions?

还应注意,了解了用于创建哈希的两个未哈希键之后,您可以从这些键重新创建哈希,而选择uuidgen解决方案作为答案是不可能的。根据您的要求,这可能是也可能不是要求。