在项目中,有个功能要求通过sql计算数据库中一年以来,某报汛测站,超过特征值水位的天数(如:超警天数),在该算法中,要求以每天的日期为关键值,计算所有满足条件的天数。由于每个测站,一天将报汛多条记录,所以要求在sql语法的构建过程中,进行区别。

     原来的方法是采用Datepart方法,对时间值进行处理。以超警天数计算过程为例,sql语句如下:

strSqlRiverWasTide = "select COUNT(distinct(DATEPART(dd,TM))) FROM ST_RIVER_R WHERE STCD = '"+watchStcdArray[i]+"' AND Z >= " + Convert.ToSingle(WRZValueArray[i]) + " AND TM >= '" + firstDateInThisYear + "'";

     从上面的语句看来,这样只会区别每天的日期值,即1-31,所以这样计算的结果将会把不同月份的相同的日期值合计为一个值,造成这样计算出来的总超警天数最大也就为31天,实际上结果应该大于31天。因此,这个问题的关键在于如何对datetime类型值进行字符串提取,再判断唯一性,需要重新构建sql语句。

    由于系统中,要求提供多种数据库接口,对于sqlServer和sybase数据库,采用Convert(data_type,expression[,style])的方式,对datetime类型值进行字符串处理;对于oracle数据库,则采用TO_CHAR(expression,style)函数来处理时间类型值。

以超警天数计算过程为例,sql代码如下:

sqlServer/sybase数据库:

strSqlRiverWasTide = "select COUNT(DISTINCT(CONVERT(varchar(10),TM,112))) FROM ST_RIVER_R WHERE STCD = '"+watchStcdArray[i]+"' AND Z >= " + Convert.ToSingle(WRZValueArray[i]) + " AND TM >= '" + firstDateInThisYear + "'";

oracle数据库:

strSqlRiverWasTide = "select COUNT(DISTINCT(TO_CHAR(TM,'yyyy-mm-dd'))) FROM ST_RIVER_R WHERE STCD = '"+watchStcdArray[i]+"' AND Z >= " + Convert.ToSingle(WRZValueArray[i]) + " AND TO_CHAR(TM,'YYYY-MM-DD HH:MM:SS') >= '" + firstDateInThisYear + "'";

 

关于Convert()的用法,请参考文章SQL中Convert转化函数的用法

关于DatePart函数的用法,请参考文章sql DATEPART函数使用

关于TO_CHAR函数的用法,请参考文章oracle to_char()函数使用方法