パススルーPROC SQLのタイムスタンプからDatePartを使用したクエリ
-
21-12-2019 - |
質問
私は、DB2パススルーPROC SQLコードでの照会場所のタイムスタンプの日付部分を使用しようとしています。日付とDatePart機能を使用してみましたが、この形式で動作しません。誰もが以下の同じコードで使用する機能の名前を知っていますか?
PROC SQL;
connect to db2(ssid=smtng);
select * from connection to db2
(select *
from ATable
where DATEPART(timestamp) > '12/01/2013'
FOR READ ONLY WITH UR
);
DISCONNECT FROM DB2;
QUIT;
. 解決
DB2のDATETIMEフィールドに関数を使用すると、データベースはインデックスを使用できません(そのフィールドが索引付けされている場合)。これは、関数によって処理された後のフィールドの結果ではなく、フィールド自体に索引が(ほとんど常に)作成されているためです。これは、DB2だけでなくデータベースの大部分のデータベースにも当てはまります。
代わりに、あなたがやりたいことは、日の初めと一日の終わりのために日付etimeの値を提供し、それらの間にすべてのものを手に入れます。このプロセスを簡単にするために、mysqldt.
という形式を作成しました。もともとこのフォーマットはMySQLデータベースのためでしたが、SQL ServerとDB2はどちらも同じ形式を使用してそれらにも使用できます。
proc format;
picture mysqldt low-high = '''%Y-%0m-%0d %0H:%0M:%0S''' (datatype = datetime) ;
run ;
.
このフォーマットが利用可能であれば、マクロ変数を使用する傾向があります。私のプログラムの上部に、私は報告書全体を通して使用する日付を指定するマクロ変数を作成します:
%let rpt_date = %sysfunc(mdy(1,12,2013));
.
その後、日の開始を表す2つの日付etimeフィールドを作成し、その日の終わりを表し、SQL文に必要な形式で保存します。
%let sql_start = %sysfunc(dhms(&rpt_date, 0, 0, 0), mysqldt.);
%let sql_end = %sysfunc(dhms(&rpt_date,23,59,59), mysqldt.);
%put &rpt_date &sql_start &sql_end;
.
このクエリを変更してこのようになります。
proc sql;
connect to db2(ssid=smtng);
select * from connection to db2
(select *
from atable
where timestamp between &sql_start and &sql_end
for read only with ur
);
quit;
.
このように、あなたの索引はあなたのクエリで使用されているだけでなく、SQLはクリーナーにされやすく読みやすく、必要に応じてレポート日を1つの場所で変更するだけでよい。あなたの報告書を再実行するために。
他のヒント
一般に、正しいDB2構文を使用する必要があります。DB2がわからないが、この論文カバーこれはかなりうまくいっています。具体的には:
PROC SQL;
CREATE TABLE ONE AS SELECT * FROM CONNECTION TO DB2
(SELECT A.ID, A.NAME, B.AMOUNT, B.POSTDATE
FROM IDS A
INNER JOIN BANK B
ON A.ID = B.ID
WHERE POSTDATE BETWEEN '2007-01-01-00.00.00.000000'
AND '2007-09-30-23.59.59.999999')
.
だからあなたのクエリは
のように見えますPROC SQL;
connect to db2(ssid=smtng);
select * from connection to db2
(select *
from ATable
where DATEPART(timestamp) > '2013-12-01-00.00.00.00000'
FOR READ ONLY WITH UR
);
DISCONNECT FROM DB2;
QUIT;
.
IBMからのこの記事タイムスタンプ以外のフォーマット(これは上記のもの)があります。そのため、正確なフォーマットに応じて別のものを使用する必要があります。
私は信じて、あなたはSAS-DATEリテラルを使うべきです。そのため:
where DATEPART(timestamp) > '12Jan2013'd
.