0

以下の db2 パススルー proc SQL コードの where クエリで、タイムスタンプの日付部分を使用しようとしています。date 関数と 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; 
4

3 に答える 3

3

DB2 の datetime フィールドで関数を使用すると、データベースはそのインデックスを使用できなくなります (そのフィールドにインデックスが付けられている場合)。これは、関数によって処理された後のフィールドの結果ではなく、(ほとんどの場合) フィールド自体にインデックスが作成されるためです。これは、DB2 だけでなく、ほとんどのデータベースに当てはまります。

代わりに、1 日の始まりと 1 日の終わりに datetime 値を指定し、それらの間のすべてを取得する必要があります。このプロセスを簡素化するために、mysqldt.. 元々、この形式は mySQL データベース用でしたが、SQL サーバーと DB2 はどちらも同じ形式を使用しているため、これらでも使用できます。

proc format;
  picture mysqldt low-high = '''%Y-%0m-%0d %0H:%0M:%0S''' (datatype = datetime) ;
run ;

この形式が利用可能になると、私はマクロ変数を使用する傾向があります。プログラムの先頭で、レポート全体で使用する日付を指定するマクロ変数を作成します。

%let rpt_date = %sysfunc(mdy(1,12,2013));

次に、1 日の開始と終了を表す 2 つの日時フィールドを作成し、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 か所 (プログラムの上部) で変更するだけで、レポートを再実行する必要があります。報告。

于 2014-06-04T18:01:43.740 に答える
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 のこの記事は、タイムスタンプ以外の形式があることを示唆しているようです (これは上記のものです)。そのため、正確な形式に応じて別のものを使用する必要がある場合があります。

于 2014-06-04T18:01:57.493 に答える
0

SAS-date リテラルを使用する必要があると思います。そう:

 where DATEPART(timestamp) > '12Jan2013'd
于 2014-06-04T17:36:03.057 に答える