简体   繁体   中英

SQL Server : best practice query for date manipulation

Long time listener, first time caller.

At work we have all of the date columns for most tables stored in as a simple "string" ( varchar ) formats. Such as yyyymmdd (eg. 20220625) or yyyymm (202206) etc.

Now for a lot of queries that are time based we need to compare to current date, or some fixed offset from current date.

Now two obvious versions that I know of to get current utc date into either of those formats are the following (for yyyymm as example):

  1. SELECT LEFT(CONVERT(VARCHAR, GETUTCDATE(), 112), 6) ...
  2. SELECT CONVERT(VARCHAR(6), GETUTCDATE(), 112) ...

I'm wondering if anyone knows of a better way, either both idiomatically or performance wise to convert those, and/or is there anything wrong with the second one to be worried about versus the first one in regards to either security/reliability etc? The second one definitely satisfies my code golf sensibilities, but not if it's at the expense of something I'm unaware of.

Also for some extra context the majority of our code runs in SQL Server or T-SQL, BUT we also need to attempt to be as platform agnostic as possible as there are customers on Oracle and/or Mysql.

Any insight/help would be highly appreciated.

There is no problem with either approach. Both work just fine. It is a matter of personal preference which to choose. The first looks more explicit, the second is shorter and thus easier to read maybe. As to performance: You want to get the current day or month only once in a query, so the call doesn't realy affect query runtime.

As to getting this platform agnostic is quite a different story. SQL dialects differ. Especially when it comes to date/time handling. You already notice that SQL Server's date functions are quite restricted. In Oracle and MySQL you would simple state the format you want ( TO_CHAR(SYSDATE, 'YYYYMM') in Oracle and DATE_FORMAT(CURRENT_DATE, '%Y%m') in MySQL). But you also see that the function calls differ.

Now, you could write a user defined function GET_CURRENT_MONTH_FORMATTED for this which would return the string for the current month, eg '202206'. Then you'd have the different codes hidden in that function and the SQL queries would all look the same. The problem, though, is how to tell the DBMS that the function result is deterministic for a particular timestamp? If you run the query on December 31, 2022 at 23:50 and it runs until January 1, 2023 at 0:20, you want the DBMS to call this function only once for the query resulting in '202212' and not being called again, suddenly resulting in another string '202301'. I don't even know whether this is possible. I guess it is not.

I think you cannot write a query that does what you want and looks the same in all mentioned DBMS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM