Вычисляемая переменная в подзапросе

У меня вопрос к экспертам PROC SQL. У меня есть этот код:

    proc sql;
    create table FinalData as 
    select * 
            ,Sum(starting_year,year_diff) as colsum
            ,Price*(1+(SELECT Return from OtherData where Year=calculated colsum)) as PriceFinal
   from MainData;
   quit;

Очевидно, что ключевое слово calculated не работает, я думаю, что для этого переменные должны быть в одном и том же списке. Я хочу иметь возможность вычислять и использовать colsum в подзапросе в одном выражении sql. Я хочу избежать пересчета colsum в каждом подзапросе, потому что в конечном итоге я буду использовать более сложные функции, которые могут замедлить код при каждом пересчете.

Я нашел этот вопрос, который кажется в значительной степени то же самое, но мне не удалось заставить код работать с этим ответом.

РЕДАКТИРОВАТЬ: немного изменил код.

На самом деле это должно было быть Year=calculated colsum. OtherData — это в основном справочная таблица, где Year не имеет дубликатов. Вот пример:

           MainData                     OtherData
  [Price] [starting_year] [year_diff]         [Return] [Year]
    5.00         2010          5                 0.04    2015
    2.33         2013          3                 0.02    2016
    4.51         2011          1                 0.005   2017
                                                 0.1     2018

Там будут пропущенные значения, и это нормально. Я знаю, что это можно легко сделать с помощью нескольких операторов proc sql, но задача состоит в том, чтобы сделать это в одном. SUM может быть любой другой функцией, которая генерирует выходные данные для поиска в OtherData.

Есть ли способ сделать это ?


person Pane    schedule 06.08.2013    source источник
comment
. . Что вы действительно пытаетесь сделать? Кажется, что в некоторых случаях подзапрос будет возвращать более одной строки, и это часто приводит к ошибке.   -  person Gordon Linoff    schedule 06.08.2013
comment
Мне кажется, что в TSQL/etc. обычно вы запускаете это как предложение WITH / запрос / что угодно, но, к сожалению, в SAS этого нет.   -  person Joe    schedule 06.08.2013
comment
Если вы предоставите больше информации о том, как выглядят основные данные и другие данные, возможно, кто-то сможет предложить лучший подход.   -  person scott    schedule 06.08.2013
comment
Я добавил пример и отредактировал для ясности. Спасибо!   -  person Pane    schedule 06.08.2013
comment
Ах. FCMP не очень хорош в 9.2; в 9.3 и (надеюсь) 9.4 лучше.   -  person Joe    schedule 06.08.2013


Ответы (1)


Одним из частичных решений конкретной проблемы является определение ваших функций как функций. SQL может быть достаточно умен, чтобы не пересчитывать одно и то же дважды, хотя, конечно, с SQL никогда не угадаешь, но попробовать стоит. По крайней мере, с скомпилированной функцией вы получаете некоторую эффективность и немного больше указателя на SQL, чтобы сделать это правильно.

proc fcmp outlib=work.funcs.test;
function bmi(weight,height);
return (weight/height**2);
endsub;
quit;
options cmplib=work.funcs;
proc sql;
select bmi(weight,height) as bmi,
        (select count(1) from sashelp.class S where bmi(s.weight,s.height) le bmi(c.weight,c.height)) as less
    from sashelp.class C;
    quit;

Вы также можете создать представление с вычисляемой переменной и использовать ее:

proc sql;
create view temp as select *, bmi(weight,height) as bmi from sashelp.class;
create table mytable as select C.*, (select count(1) from sashelp.class S where bmi(s.weight,s.height) le C.bmi) from temp C;
quit;
person Joe    schedule 06.08.2013
comment
Поворот сюжета в том, что я уже использую fcmp и, к сожалению, значения каждый раз пересчитываются. Что еще хуже, fcmp плохо взаимодействует с sql и иногда приводит к сбою сеанса при пересчете. Я понятия не имею, что такое представление, но я попробую. Спасибо ! - person Pane; 06.08.2013
comment
Представление — это фактически инструкции по созданию таблицы без ее фактического создания. Однако к нему можно получить доступ идентично (в основном) таблице, что удобно для такого рода вещей. - person Joe; 06.08.2013