首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SAS升级到9.4M7后Oracle数据库中的最小函数行为

SAS升级到9.4M7后Oracle数据库中的最小函数行为
EN

Stack Overflow用户
提问于 2021-12-22 09:30:48
回答 3查看 101关注 0票数 0

我有一个工作多年的计划。今天,我们从SAS 9.4M3升级到9.4M7。

代码语言:javascript
复制
proc setinit
Current version: 9.04.01M7P080520

从那以后,我无法获得与升级前相同的结果。

请注意,我正在直接查询Oracle数据库。

为了用一个最小的、可重复的SAS表示例来复制这个问题,我发现这个问题在查询SAS表而不是在Oracle数据库上时消失了。

假设我有以下数据集:

代码语言:javascript
复制
data have;
infile datalines delimiter="|";
input name :$8. id $1. value :$8. t1 :$10.;
datalines;
Joe|A|TLO
Joe|B|IKSK
Joe|C|Yes
;

使用临时表:

代码语言:javascript
复制
proc sql;
    create table want as
    select name,
    min(case when id = "A" then value else "" end) as A length 8
    from have
    group by name;
quit; 

Results:

name   A
Joe   TLO

但是,当直接在oracle数据库上运行相同的查询时,我会得到一个缺失的值:

代码语言:javascript
复制
proc sql;
    create table want as
      select name, 
      min(case when id = "A" then value else "" end) as A length 8
      from have_oracle
      group by name;
quit;

name     A
Joe       

根据文档,当在SAS表上使用时,min()函数运行正常。

-- MIN函数只有在所有参数都缺少时才返回缺少的值(.) 。

我相信,当Oracle不理解SAS传递它的函数时,就会发生这种情况-- SAS和Oracle中的min函数非常不同,在SAS中的等效函数是LEAST()

因此,我的猜测是,升级将如何将SAS函数转换为Oracle,但这仍然是一个猜测。有人遇到过这种行为吗?

编辑:@Richard的评论

代码语言:javascript
复制
options sastrace=',,,d' sastraceloc=saslog nostsuffix;

proc sql;
    create table want as
    select t1.name,
    min(case when id = 'A' then value else "" end) as A length 8
    from oracle_db.names t1 inner join oracle_db.ids t2 on (t1.tid = t2.tid)
    group by t1.name;
    
ORACLE_26: Prepared: on connection 0
SELECT * FROM NAMES
 
ORACLE_27: Prepared: on connection 1
SELECT  UI.INDEX_NAME, UIC.COLUMN_NAME FROM  USER_INDEXES UI,USER_IND_COLUMNS UIC WHERE  UI.TABLE_NAME='NAMES' AND 
UIC.TABLE_NAME='NAMES' AND  UI.INDEX_NAME=UIC.INDEX_NAME
 
ORACLE_28: Executed: on connection 1
SELECT statement  ORACLE_27
 
ORACLE_29: Prepared: on connection 0
SELECT * FROM IDS
 
ORACLE_30: Prepared: on connection 1
SELECT  UI.INDEX_NAME, UIC.COLUMN_NAME FROM  USER_INDEXES UI,USER_IND_COLUMNS UIC WHERE  UI.TABLE_NAME='IDS' AND 
UIC.TABLE_NAME='IDS' AND  UI.INDEX_NAME=UIC.INDEX_NAME
 
ORACLE_31: Executed: on connection 1
SELECT statement  ORACLE_30
 
ORACLE_32: Prepared: on connection 0
select t1."NAME", MIN(case  when t2."ID" = 'A' then t1."VALUE" else ' ' end) as A from 
NAMES t1 inner join IDS t2 on t1."TID" = t2."TID" group by t1."NAME"
 
ORACLE_33: Executed: on connection 0
SELECT statement  ORACLE_32
 
ACCESS ENGINE:  SQL statement was passed to the DBMS for fetching data. 
NOTE: Table WORK.SELECTED_ATTR created, with 1 row and 2 columns.

!                              quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.34 seconds
      cpu time            0.09 seconds
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-12-22 11:50:10

使用SASTRACE=系统选项记录发送给DBMS的SQL语句。

代码语言:javascript
复制
options SASTRACE=',,,d';

将提供最详细的日志记录。

从准备好的语句中,您可以看到为什么要从Oracle查询中获得空白。

代码语言:javascript
复制
select 
  t1."NAME"
, MIN ( case
          when t2."ID" = 'A' then t1."VALUE" 
          else ' '
        end
      ) as A 
from 
  NAMES t1 inner join IDS t2 on t1."TID" = t2."TID" 
group by
  t1."NAME"

SQL ()聚合函数将排除空值。

在SQL中,空白值也被解释为null。

在SAS中,SQL查询返回min非空值TLO

在Oracle查询中,SAS空白''被转换为' ' (一个空字符),该字符为非空字符,因此' ' < 'TLO'和您将得到空白结果。

在甲骨文中要强制执行的实际分钟是min(case when id = "A" then value else null end)@Tom通过省略子句显示这一点是可能的。

查看实际差异的唯一方法是在前面的SAS版本中使用跟踪运行查询,或者如果幸运的话,请参阅(许多人忽略的) "What's New“文档中的解释。

票数 3
EN

Stack Overflow用户

发布于 2021-12-22 13:59:53

为什么要使用' '''作为其他值?也许Oracle对带有空格的字符串的处理方式与空字符串不同。

为什么不在clause子句中使用null呢?

或者干脆去掉off子句,让它默认为null

代码语言:javascript
复制
libname mylib oracle .... ;
proc sql;
  create table want as
    select name
         , min(case when id = "A" then value else null end) as A length 8
    from mylib.have_oracle
    group by name
  ;
quit;

还可以尝试自己运行Oracle代码,而不是使用隐式pass。

代码语言:javascript
复制
proc sql;
  connect to oracle ..... ;
  create table want as
    select * from connection to oracle
     (
      select name, 
      min(case when id = "A" then value else null end) as A length 8
      from have_oracle
      group by name
     )
  ;
quit;
票数 2
EN

Stack Overflow用户

发布于 2021-12-22 10:15:11

当我试图在Oracle中复制这个结果时,我得到了您正在寻找的结果,因此我怀疑它与SAS有关(我不熟悉)。

代码语言:javascript
复制
with t as (
  select 'Joe' name, 'A' id, 'TLO' value from dual union all
  select 'Joe' name, 'B' id, 'IKSK' value from dual union all
  select 'Joe' name, 'C' id, 'Yes' value from dual
)
select name
, min(case when id = 'A' then value else '' end) as a
from t
group by name;


NAME A   
---- ---- 
Joe  TLO

如果您只对id = 'A‘感兴趣,那么更好的查询是:

代码语言:javascript
复制
select name
, min(value) as a
from t
where id = 'A'
group by name;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70446875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档