sas proc-sql

sas - Limitando resultados en PROC SQL



proc-sql (2)

Estoy tratando de usar PROC SQL para consultar una tabla de DB2 con cientos de millones de registros. Durante la etapa de desarrollo, quiero ejecutar mi consulta en un subconjunto arbitrariamente pequeño de esos registros (digamos, 1000). Intenté usar INOBS para limitar las observaciones, pero creo que este parámetro simplemente limita el número de registros que procesa SAS. Quiero que SAS solo obtenga un número arbitrario de registros de la base de datos (y luego los procese).

Si estuviera escribiendo una consulta SQL, simplemente usaría SELECT * FROM x FETCH FIRST 1000 ROWS ONLY ... (el equivalente de SELECT TOP 1000 * FROM x en SQL Server). Pero PROC SQL no parece tener ninguna opción como esta. Se está tomando un tiempo extremadamente largo para obtener los registros.

La pregunta: ¿cómo puedo instruir a SAS para que limite arbitrariamente la cantidad de registros a devolver desde la base de datos ?

He leído que PROC SQL usa ANSI SQL, que no tiene ninguna especificación para una palabra clave que limite la fila. Quizás SAS no tuvo ganas de hacer el esfuerzo de traducir su sintaxis SQL a palabras clave específicas del proveedor. ¿No hay trabajo?


¿Has probado usar la opción outobs en tu proc sql ?

Por ejemplo,

proc sql outobs=10; create table test as select * from schema.HUGE_TABLE order by n; quit;

Alternativamente, puede usar el paso directo de SQL para escribir una consulta utilizando la sintaxis de DB2 ( FETCH FIRST 10 ROWS ONLY ), aunque esto requiere que almacene todos sus datos en la base de datos, al menos temporalmente.

Passthrough se ve así:

proc sql; connect to db2 (user=&userid. password=&userpw. database=MY_DB); create table test as select * from connection to db2 ( select * from schema.HUGE_TABLE order by n FETCH FIRST 10 ROWS ONLY ); quit;

Requiere más sintaxis y no puede acceder a los conjuntos de datos sas, por lo que si outobs funciona para usted, lo recomendaría.


Cuando SAS está hablando con una base de datos a través de la sintaxis SAS, parte de la consulta se puede traducir al equivalente del lenguaje DBMS; esto se denomina paso implícito. El resto de la consulta es "postprocesada" por SAS para producir el resultado final. Dependiendo de la versión SAS, el proveedor DBMS y la versión DBMS, y en algunos casos incluso algunas opciones de conexión / nombre de liba, diferentes partes de la sintaxis SAS son traducibles / consideradas compatibles entre SAS y DBMS y enviados por DBMS en lugar de SAS.

Con las opciones de SAS SQL - INOBS y OUTOBS - he trabajado mucho con MS SQL y Oracle a través de diferentes versiones de SAS, pero no he visto las que alguna vez se hayan traducido al tipo de consultas TOP xxx, por lo que probablemente aún no se admite, aunque cuando la consulta solo toca datos de DMBS (no se une a los datos SAS, etc.), debería ser bastante factible.

Así que creo que se queda con la llamada sintaxis SQL SAS específica del paso explícito para conectarse a la base de datos. Este tipo de consultas se ve así:

proc sql; connect to oracle as db1 (user=user1 pw=pasw1 path=DB1); create table test_table as select * from connection to db1 ( /* here we''re in oracle */ select * from test.table1 where rownum <20 ) ; disconnect from db1; quit;

En SAS 9.3, la sintaxis se puede simplificar: si ya hay una conexión LIBNAME, puede reutilizarla para una transferencia explícita:

LIBNAME ORALIB ORACLE user=...; PROC SQL; connect to oracle using ORALIB; create table work.test_table as select * from connection to ORALIB ( ....

Al conectar con nombre de lib, asegúrese de usar READBUFF (normalmente configuro unas 5000 o más) o INSERTBUFF options (1000 o más) al cargar la base de datos.

Para ver si se produce el paso implícito, configure la opción sastrace:

option sastrace='',,,ds'' sastraceloc=saslog nostsuffix;