Лучший способ, которым я нашел для обработки этих сценариев, - использовать пользовательский формат даты и времени. Вы можете найти ссылку на их создание here. Я рекомендую сохранить формат в общей библиотеке, чтобы он всегда был доступен для ваших сеансов SAS. Формат будет:
proc format ;
picture mssqldt low-high = '''%Y-%0m-%0d %0H:%0M:%0S.000''' (datatype = datetime) ;
run ;
Это займет регулярный SAS DATETIME штамп и отформатировать его, как это (включая кавычки):
'2015-09-21 15:04:16.000'
лучший способ включить это в код SAS, чтобы всегда сохраняйте свои даты и дату в своем представлении SAS и имеете отдельные переменные для ваших форматированных переменных SQL-сервера. Например.
Вычислить DateTime мы хотим работать с:
%let my_datetime = %sysfunc(datetime());
Создать две новые переменные с SQL сервером отформатированных штампов даты и времени. Я всегда называю моим &sql_start
и &sql_end
так, что они читают хорошо, и я никогда не должен думать об этом ...
%let sql_start = %sysfunc(sum(&my_datetime),mssqldt.);
%let sql_end = %sysfunc(intnx(minute,&my_datetime,1),mssqldt.);
Вы можете видеть, что для расчета sql_start
я использовал функцию sum()
в %sysfunc()
и передается в DateTime SAS переменная. Я делаю это так, потому что он не меняет значение datetime и позволяет мне использовать второй параметр %sysfunc()
, который применяет указанный формат к возвращаемому значению.
Для sql_end
Я использовал функцию intnx()
в обычном режиме и снова использовал второй параметр %sysfunc()
для его форматирования.
Давайте распечатать значения, чтобы увидеть, как они выглядят:
%put &sql_start &sql_end;
Дает:
'2015-09-21 15:04:16.000' '2015-09-21 15:05:00'
Тогда это просто случай использования его в коде следующим образом:
proc sql;
...
where tmstmp between &sql_start and &sql_end;
quit;
Вот весь код в одном споре т (если вы уже определили формат):
%let my_datetime = %sysfunc(datetime());
%let sql_start = %sysfunc(sum(&my_datetime),mssqldt.);
%let sql_end = %sysfunc(intnx(minute,&my_datetime,1),mysqldt.);
%put &sql_start &sql_end;
proc sql;
...
where tmstmp between &sql_start and &sql_end;
quit;
Теперь, если вы хотите, чтобы вытащить данные одну часть за один раз, вы можете скомпилировать все это в петлю, как это:
%macro get_data(iStart=,iEnd=);
%local tmp_start tmp_end sql_start sql_end;
%let tmp_start = &iStart;
%do %while(&tmp_start le &iEnd);
%let tmp_end = %sysfunc(intnx(hour,&tmp_start,0,end));
/* MAKE SURE END OF LOOP ISNT GREATER THAN END DATETIME */
%if &tmp_end > &iEnd %then %do;
%let tmp_end = &iEnd;
%end;
%let sql_start = %sysfunc(sum(&tmp_start),mssqldt.);
%let sql_end = %sysfunc(sum(&tmp_end ),mssqldt.);
/* DO SQL HERE */
%put &sql_start &sql_end;
/* INCREMENT THE LOOP */
%let tmp_start = %sysfunc(intnx(hour,&tmp_start,1,beginning));
%end;
%mend;
Называйте это на сегодняшний день до некоторого времени завтра:
%get_data(iStart=%sysfunc(datetime()),
iEnd =%sysfunc(dhms(%sysfunc(date())+1,2,30,13))
);
Получаемые пробеги за следующие периоды:
'2015-09-21 15:25:33.000' '2015-09-21 15:59:59.000'
'2015-09-21 16:00:00.000' '2015-09-21 16:59:59.000'
'2015-09-21 17:00:00.000' '2015-09-21 17:59:59.000'
'2015-09-21 18:00:00.000' '2015-09-21 18:59:59.000'
'2015-09-21 19:00:00.000' '2015-09-21 19:59:59.000'
'2015-09-21 20:00:00.000' '2015-09-21 20:59:59.000'
'2015-09-21 21:00:00.000' '2015-09-21 21:59:59.000'
'2015-09-21 22:00:00.000' '2015-09-21 22:59:59.000'
'2015-09-21 23:00:00.000' '2015-09-21 23:59:59.000'
'2015-09-22 00:00:00.000' '2015-09-22 00:59:59.000'
'2015-09-22 01:00:00.000' '2015-09-22 01:59:59.000'
'2015-09-22 02:00:00.000' '2015-09-22 02:30:13.000'
Замечательный ответ Роберт - именно то, что я хотел. Спасибо, что нашли время, чтобы написать его подробно. – milcak