【问题标题】:Order of rows returned by PROC SQLPROC SQL 返回的行的顺序
【发布时间】:2015-04-21 17:54:14
【问题描述】:

如果没有sortgroup by 语句,我想知道PROC SQL 返回数据的顺序。总是一样吗?

例如,假设我这样做:

proc sql;
    create table cusips as
        select a.cusip as c1, b.cusip as c2
        from shrs a, shrs b;
quit;

这只是给了我两个 cusip 变量的每个组合的列表。这些顺序是否与原始输入数据中的顺序相同?看起来我的情况就是这样,但我想知道我是否可以确定这将永远是正确的。

【问题讨论】:

  • SQL 中的表和结果集(与 SAS 不同)表示 无序 集。您不能依赖结果集中值的顺序,除非您指定了 order by 子句。

标签: sql sas proc-sql


【解决方案1】:

PROC SQL 不保证在任何 情况下的相同顺序。 一般来说,如果您从单个表中进行简单的选择,它可能会按照数据已经存在的顺序返回,主要是因为不这样做会带来更多的工作。

然而,PROC SQL 如果它决定这样做是最佳的,它将执行诸如将数据拆分成块并并行单独处理它们之类的事情 - 可能不像它应该那样多,但它有时会。 join 经常发生这种情况,特别是因为它可能作为哈希连接执行,在这种情况下,您可以按一个表的顺序或两者,或者笛卡尔积或其他一些选项来获取它。

特别是,在上面的连接中,SQL 优化器可能会选择将其作为笛卡尔积、哈希连接、索引连接或其他几种方法。它们中的每一个都可能导致不同的结果。即使在此范围内,如果连接是通过多个线程完成的,线程的平衡可能会有所不同,具体取决于当时执行它的服务器/计算机的条件(即,如果一个 CPU 承受更多/更少的负载从其他进程,它可能会得到更少/更多的数据)。

因此,您永远不应依赖它按顺序返回数据 - 始终要求按顺序返回数据。

这也是为什么不建议将 monotonic() 函数用于生产代码的原因(因为如果最终订单与原始订单不同,它可能不会总是返回预期值)。

如果您希望按原始顺序取回数据,但不知道原始顺序或不想指定完整顺序,一个好的解决方法是使用 datastep 视图获取原始顺序。 Datastep 视图将按顺序处理数据。

data myview/view=myview;
  set mydata;
  _ordervar+1;
run;

proc sql;
  select * from myview
    order by _ordervar;
quit;

【讨论】:

    猜你喜欢
    • 2012-05-12
    • 1970-01-01
    • 2023-03-20
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2023-03-09
    相关资源
    最近更新 更多