Ограничение результатов в PROC SQL

Я пытаюсь использовать PROC SQL для запроса таблицы DB2 с сотнями миллионов записей. На этапе разработки я хочу запустить свой запрос на произвольно малом подмножестве этих записей (скажем, 1000). Я попытался использовать INOBS для ограничения наблюдений, но я считаю, что этот параметр просто ограничивает количество записей, обрабатываемых SAS. Я хочу, чтобы SAS извлекал только произвольное количество записей из базы данных (а затем обрабатывал их все).

Если бы я сам писал SQL-запрос, я бы просто использовал SELECT * FROM x FETCH FIRST 1000 ROWS ONLY ... (эквивалент SELECT TOP 1000 * FROM x в SQL Server). Но у PROC SQL, похоже, нет такого варианта. Для получения записей требуется очень много времени.

Вопрос: как я могу дать указание SAS произвольно ограничить количество записей возвратом из базы данных.

Я читал, что PROC SQL использует ANSI SQL, у которого нет спецификации для ключевого слова, ограничивающего строку. Возможно, SAS не хотел прилагать усилия для перевода своего синтаксиса SQL к ключевым словам для конкретных поставщиков? Нет работы?

Ответы

Ответ 1

Когда SAS разговаривает с базой данных через синтаксис SAS, часть запроса может быть переведена на эквивалент языка СУБД - это называется неявным прохождением. Остальная часть запроса является "пост-обработанной" SAS для получения конечного результата. В зависимости от версии SAS, версии СУБД и версии СУБД, а в некоторых случаях даже некоторых параметров соединения /libname разные части синтаксиса SAS могут быть переводимыми/считаемыми совместимыми между SAS и СУБД и, таким образом, отправляться для выполнения СУБД вместо SAS.

С параметрами SAS SQL - INOBS и OUTOBS - я много работал с MS SQL и Oracle через разные версии SAS, но я не видел тех, кто когда-либо переводился в запросы типа TOP xxx, так что это, вероятно, не но когда запрос затрагивает только данные DMBS (нет подключений к данным SAS и т.д.), должен быть вполне выполнимым.

Итак, я думаю, что вы остаетесь с так называемым явным синтаксисом SAS SQL для передачи данных в базу данных. Этот тип запросов выглядит следующим образом:

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;

В SAS 9.3 синтаксис может быть упрощен - если у вас уже есть соединение LIBNAME, вы можете повторно использовать его для явного прохода:

LIBNAME ORALIB ORACLE user=...;

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

При загрузке базы данных при подключении с помощью libname обязательно используйте READBUFF (обычно я устанавливаю около 5000 или около того) или INSERTBUFF (1000 или более).

Чтобы узнать, имеет место неявный проход, установите параметр sastrace:

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

Ответ 2

Пробовали ли вы использовать параметр outobs в proc sql?

Например,

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

В качестве альтернативы вы можете использовать пересылку SQL для записи запроса с использованием синтаксиса DB2 (FETCH FIRST 10 ROWS ONLY), хотя для этого требуется, чтобы вы сохраняли все свои данные в базе данных, по крайней мере временно.

Passthrough выглядит примерно так:

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;

Он требует большего синтаксиса и не может получить доступ к вашим наборам данных sas, поэтому, если outobs работает для вас, я бы рекомендовал это.