在直通 Proc SQL 中使用时间戳中的日期部分进行查询
-
21-12-2019 - |
题
我试图在下面的 db2 pass-through proc SQL 代码中的 where 查询中使用时间戳的日期部分。我尝试使用日期和日期部分函数,但它不适用于这种格式。有谁知道下面相同代码中使用的函数名称?
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 中的日期时间字段上使用函数,那么数据库将无法使用它的索引(如果该字段已建立索引)。这是因为索引(几乎总是)是在字段本身上创建的,而不是在函数处理字段后的结果上创建的。这对于大多数数据库都适用,而不仅仅是 DB2。
相反,您想要做的是提供一天开始和一天结束的日期时间值,并获取它们之间的所有内容。为了简化这个过程,我创建了一种名为 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));
然后,我将创建两个代表一天开始和一天结束的日期时间字段,并以 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 看起来更干净并且更易于阅读,并且如果您需要重新运行您的程序,您只需在一个位置(在程序的顶部)更改报告日期。报告。
其他提示
一般来说,您需要使用正确的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日期文字。所以:
where DATEPART(timestamp) > '12Jan2013'd
. 不隶属于 StackOverflow