我有一個已經運行多年的程式。今天,我們從 SAS 9.4M3 升級到 9.4M7。
proc setinit
Current version: 9.04.01M7P080520
從那以后,我無法獲得與升級前相同的結果。
請注意,我直接查詢 Oracle 資料庫。
嘗試使用最小的、可重現的 SAS 表示例來復制問題,我發現在 SAS 表而不是 Oracle 資料庫上查詢時問題消失了。
假設我有以下資料集:
data have;
infile datalines delimiter="|";
input name :$8. id $1. value :$8. t1 :$10.;
datalines;
Joe|A|TLO
Joe|B|IKSK
Joe|C|Yes
;
使用臨時表:
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 資料庫上運行完全相同的查詢時,我得到了一個缺失值:
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
根據檔案,該min()函式在 SAS 表上使用時運行正常
MIN 函式僅在所有引數都缺失時才回傳缺失值 (.) 。
我相信當 Oracle 不理解 SAS 傳遞它的函式時會發生這種情況 - SAS 和 Oracle 中的 min 函式非常不同,而 SAS 中的等效函式是LEAST().
所以我的猜測是升級搞砸了如何將 SAS min 函式轉換為 Oracle,但它仍然是一個猜測。有沒有人遇到過這種行為?
編輯:@Richard 的評論
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
uj5u.com熱心網友回復:
當我嘗試在 Oracle 中重現它時,我得到了您正在尋找的結果,所以我懷疑它與 SAS(我不熟悉)有關。
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' 感興趣,那么更好的查詢是:
select name
, min(value) as a
from t
where id = 'A'
group by name;
uj5u.com熱心網友回復:
使用SASTRACE=系統選項記錄發送到 DBMS 的 SQL 陳述句。
options SASTRACE=',,,d';
將提供最詳細的日志記錄。
uj5u.com熱心網友回復:
你為什么使用' '或''作為 ELSE 值?或許 Oracle 將包含空格的字串與空字串的處理方式不同。
為什么不在nullELSE 子句中使用?
或者只是不使用 ELSE 子句并讓它默認為null?
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 代碼,而不是使用隱式傳遞。
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;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/389863.html
