gpt4 book ai didi

sas - 基于不存在列的Proc sql子查询返回不为空

转载 作者:行者123 更新时间:2023-12-02 20:33:04 28 4
gpt4 key购买 nike

这里是来自实际应用的示例代码。有两个数据集 - “aa”用于查询,“bb”用于子查询。数据集“aa”中的列“m”与数据集“bb”中的列“y”匹配。此外,“aa”表上的“yy”列的值为 30。数据集“aa”中的列“m”在其某一行中包含值“30”,数据集“bb”中的列“y”包含值“30”不是。第一个 proc sql 根据“m”列中的匹配值,使用“bb”表的“y”列中的值来创建子表“aa”。这是一个正确的查询并产生预期的结果。第二个 proc sql block 在以 where 语句开头的行中的子查询中故意将列“y”拼写错误为“yy”。否则整个 proc sql block 与第一个相同。鉴于数据集 bb 上没有列“yy”,我希望出现错误消息并且整个查询失败。但是,它确实返回一行,而没有失败或错误消息。仔细观察会发现它实际上使用表“aa”中的“yy”列(请参阅日志输出中的树)。我认为这不是正确的行为。如果您有任何意见或解释,我将不胜感激。否则,我也许应该将其作为错误报告给 SAS。谢谢!

这是代码:

options 
msglevel = I
;
data aa;
do i=1 to 20;
m=i*5;
yy=30;
output;
end;
run;

data bb;
do i=10 to 20;
y=i*5;
output;
end;
run;
option DEBUG=JUNK ;

/*Correct sql command*/
proc sql _method
_tree
;
create table cc as
select *
from aa
where m in (select y from bb)
;quit;


/*Incorrect sql command - column "yy" in not on "bb" table"*/
proc sql _method
_tree;
create table dd as
select *
from aa
where m in (select yy from bb)
;quit;

这是带有 sql 树的日志:

119      options
120 msglevel = I
121 ;
122 data aa;
123 do i=1 to 20;
124 m=i*5;
125 yy=30;
126 output;
127 end;
128 run;

NOTE: The data set WORK.AA has 20 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


129
130 data bb;
131 do i=10 to 20;
132 y=i*5;
133 output;
134 end;
135 run;

NOTE: The data set WORK.BB has 11 observations and 2 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


136 option DEBUG=JUNK ;
137
138 /*Correct sql command*/
139 proc sql _method
140 _tree
141 ;
142 create table cc as
143 select *
144 from aa
145 where m in (select y from bb)
146 ;

NOTE: SQL execution methods chosen are:

sqxcrta
sqxfil
sqxsrc( WORK.AA )

NOTE: SQL subquery execution methods chosen are:

sqxsubq
sqxsrc( WORK.BB )

Tree as planned.
/-SYM-V-(aa.i:1 flag=0001)
/-OBJ----|
| |--SYM-V-(aa.m:2 flag=0001)
| \-SYM-V-(aa.yy:3 flag=0001)
/-FIL----|
| | /-SYM-V-(aa.i:1 flag=0001)
| | /-OBJ----|
| | | |--SYM-V-(aa.m:2 flag=0001)
| | | \-SYM-V-(aa.yy:3 flag=0001)
| |--SRC----|
| | \-TABL[WORK].aa opt=''
| | /-SYM-V-(aa.m:2)
| \-IN-----|
| | /-SYM-V-(bb.y:2 flag=0001)
| | /-OBJ----|
| | /-SRC----|
| | | \-TABL[WORK].bb opt=''
| \-SUBC---|
--SSEL---|


NOTE: Table WORK.CC created, with 11 rows and 3 columns.

146! quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds


147
148
149 /*Incorrect sql command - column "yy" in not on "bb" table"*/
150 proc sql _method
151 _tree;
152 create table dd as
153 select *
154 from aa
155 where m in (select yy from bb)
156 ;

NOTE: SQL execution methods chosen are:

sqxcrta
sqxfil
sqxsrc( WORK.AA )

NOTE: SQL subquery execution methods chosen are:

sqxsubq
sqxreps
sqxsrc( WORK.BB )

Tree as planned.
/-SYM-V-(aa.i:1 flag=0001)
/-OBJ----|
| |--SYM-V-(aa.m:2 flag=0001)
| \-SYM-V-(aa.yy:3 flag=0001)
/-FIL----|
| | /-SYM-V-(aa.i:1 flag=0001)
| | /-OBJ----|
| | | |--SYM-V-(aa.m:2 flag=0001)
| | | \-SYM-V-(aa.yy:3 flag=0001)
| |--SRC----|
| | \-TABL[WORK].aa opt=''
| | /-SYM-V-(aa.m:2)
| \-IN-----|
| | /-SYM-A-(#TEMA001:1 flag=0035)
| | /-OBJ----|
| | /-REPS---|
| | | |--empty-
| | | |--empty-
| | | | /-OBJ----|
| | | |--SRC----|
| | | | \-TABL[WORK].bb opt=''
| | | |--empty-
| | | |--empty-
| | | | /-SYM-A-(#TEMA001:1 flag=
0035)
| | | | /-ASGN---|
| | | | | \-SUBP(1)
| | | \-OBJE---|
| \-SUBC---|
| \-SYM-V-(aa.yy:3)
--SSEL---|


NOTE: Table WORK.DD created, with 1 rows and 3 columns.

156! quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

以下是数据集:

aa:
i m yy
1 5 30
2 10 30
3 15 30
4 20 30
5 25 30
6 30 30
7 35 30
8 40 30
9 45 30
10 50 30
11 55 30
12 60 30
13 65 30
14 70 30
15 75 30
16 80 30
17 85 30
18 90 30
19 95 30
20 100 30

bb:
i y
10 50
11 55
12 60
13 65
14 70
15 75
16 80
17 85
18 90
19 95
20 100

最佳答案

我同意,这看起来很奇怪,很可能是一个错误。我能够从您在 SAS 9.4 和 SAS 9.1.3 中提供的代码中重现这一点,这将使其至少有约 12 年的历史。

特别是,我对创建 DD 表时从 _method 选项获得的输出感兴趣,但对创建 CC 表时不感兴趣:

NOTE: SQL subquery execution methods chosen are:

sqxsubq
sqxreps <--- What is this doing?
sqxsrc( WORK.BB )

同样,_tree 输出中的相应部分非常模糊:

          |                   |                              /-SYM-A-(#TEMA001:1 flag=0035)
| | /-OBJ----|
| | /-REPS---|
| | | |--empty-
| | | |--empty-
| | | | /-OBJ----|
| | | |--SRC----|
| | | | \-TABL[WORK].bb opt=''
| | | |--empty-
| | | |--empty-
| | | | /-SYM-A-(#TEMA001:1 flag= 0035)
| | | | /-ASGN---|
| | | | | \-SUBP(1)
| | | \-OBJE---|
| \-SUBC---|
| \-SYM-V-(aa.yy:3)

我以前从未在输出的相应位中见过 sqxrepsreps。我通过简短的谷歌搜索找到的任何论文中都没有列出它们(事实上,这个问题目前是 Google 上关于 sas + sqxreps 的唯一热门问题):

http://support.sas.com/resources/papers/proceedings10/139-2010.pdf http://www2.sas.com/proceedings/sugi30/101-30.pdf

引用其中第一条:

Codes    Description
sqxcrta Create table as Select
Sqxslct Select
sqxjsl Step loop join (Cartesian)
sqxjm Merge join
sqxjndx Index join
sqxjhsh Hash join
sqxsort Sort
sqxsrc Source rows from table
sqxfil Filter rows
sqxsumg Summary stats with GROUP BY
sqxsumn Summary stats with no GROUP BY

根据一些快速测试,无论使用什么变量和表名称,只要 AA 中的变量名称在引用表 BB 的子查询中重复多次,这种情况似乎都会发生。如果您有一个名为例如的变量,也会发生这种情况。 AA 中为 YYY,但 BB 中名为 YY,或者更一般地说,每当 BB 中有一个变量,其名称最初与 AA 中相应变量的名称相同,但随后继续包含一个或多个字符。

由此,我猜测在 SQL 解析器中的某个时刻,有人使用了 like 运算符而不是检查变量名称的相等性,并且不知何故,此语法触发了未记录的错误或 proc sql 中的“功能”不完整。

更一般情况的示例:

options 
msglevel = I
;
data aa;
do i=1 to 20;
m=i*5;
myvar_plus_suffix=30;
output;
end;
run;

data bb;
do i=10 to 20;
myvar=i*5;
output;
end;
run;
option DEBUG=JUNK ;

/*Incorrect sql command - column "yy" in not on "bb" table"*/
proc sql _method
_tree;
create table dd as
select *
from aa
where m in (select myvar_plus_suffix from bb)
;quit;

关于sas - 基于不存在列的Proc sql子查询返回不为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34185428/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com