需要帮助而无需对某些数据进行排序

时间:2019-08-09 02:02:13

标签: sas teradata

我在将SAS代码转换为SQL时遇到问题。有一行代码涉及从SAS排序表的某些行,我似乎无法复制到SQL。

我尝试通过分区子句使用不同类型的row_number,甚至尝试使用唯一标识符对行进行排序,但是我总是获得与SAS代码不同的结果。

data Testing;                                           
input col1$ col2$ col3$ col4$ col5$ col6$ col7$ new;       
datalines;                       
7.3 11 11 A AAB 1245 20 1               
7.3 11 11 A AAB 1245 20 32             
;

proc sort data = Testing nodupkey;
by col1 col2 col3 col4 col5 col6;

对于上面的SAS代码,我的结果是以下行:

7.3 11 11 A AAB 1245 20 1   

,它是“测试”表上的第一行。

但是,如果我尝试在Teradata中使用任何涉及行号和分区的代码,我总是获得第二行:

7.3 11 11 A AAB 1245 20 32

据我了解,SQL不应该以任何特定顺序存储行,而SAS可以。我试图找到一种在SQL中复制此SAS排序过程的方法,但是我总是得到不同的结果。

如果有帮助,我当前正在运行此SQL查询:

select * from Testing                 
qualify row_number() over (partition by col1, col2, col3, col4, col5, col6 order by col1 asc, col2 asc, col3 asc, col4 asc, col5 asc, col6 asc)=1

我尝试按部分顺序使用asc或desc,但是无论哪种情况,我都获得第二行而不是第一行。

提前谢谢!

2 个答案:

答案 0 :(得分:1)

PROC SORTNODUPKEY选项一起使用时,它将在输入数据集中保留其遇到的第一条记录。此行为由EQUALS / NOEQUALS选项控制。

根据文档“ EQUALS是默认值。对于具有相同BY变量值的观测,EQUALS会维护输出数据集中输入数据集的顺序。NOEQUALS不一定会在输出数据集中保留此顺序。 。NOEQUALS可以节省CPU时间和内存资源。“

我不是TD方面的专家,但据我所知,正如您正确地说的那样,Terradata没有行号的概念,因此没有默认顺序。您正在使用的代码只是在结果中即时分配row_number,而不是实际的基础数据-这将导致每次尝试拉相同记录的尝试都分配不同的内容。

我假设您正在尝试通过在TD中的SAS和SQL中获得相同的结果来验证代码。如果您确实想要相同的结果,建议您在TD中创建一个唯一的标识符,从中重新提取以重新创建SAS数据集,然后将该ID用作排序等的一部分。或者,您可能必须依赖于其他列以获取相同的记录。

答案 1 :(得分:0)

仅当您在查询中使用ORDER BY子句时,SQL语言才保证行的顺序。当多个观察结果属于同一ORDER BY组时,不同的实现(或同一实现中的不同优化)可能会产生不同的顺序。

SAS将数据存储在已定义观察顺序的物理文件中。因此,通常,其实现将按最初在数据集中的顺序返回同一组的观测值。 Teradata没有类似的概念。它并行存储和分析数据。任何给定的运行都将按不同处理器恰好完成生成它们的顺序返回行。

因此,您需要具有一个(或多个)变量,可用于重新创建订单。

您可以将变量添加到SAS数据集中,然后将其重新加载到Teradata中。例如,像这样的简单步骤将为每个观察值生成唯一的ROWID值。

 data want;
    rowid + 1;
    set have;
 run;

然后,您可以在ROW_NUMBER()函数调用中使用ROWID。

select * 
  from Testing_with_rowid
  qualify 1=row_number() over 
    (partition by col1, col2, col3, col4, col5, col6 
     order by rowid)
  order by col1, col2, col3, col4, col5, col6 
;