简体   繁体   English

SQL Server:日期操作的最佳实践查询

[英]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.在工作中,我们将大多数表的所有日期列存储为简单的“字符串”( varchar ) 格式。 Such as yyyymmdd (eg. 20220625) or yyyymm (202206) etc.yyyymmdd (如 20220625)或 yyyymm(202206)等。

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):现在,我知道将当前 utc 日期转换为其中任何一种格式的两个明显版本如下(以 yyyymm 为例):

  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.此外,对于一些额外的上下文,我们的大部分代码都在 SQL Server 或 T-SQL 中运行,但我们还需要尽可能地与平台无关,因为 Oracle 和/或 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. SQL 方言不同。 Especially when it comes to date/time handling.特别是在日期/时间处理方面。 You already notice that SQL Server's date functions are quite restricted.您已经注意到 SQL Server 的日期函数非常有限。 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).在 Oracle 和 MySQL 中,您可以简单地声明您想要的格式(Oracle 中TO_CHAR(SYSDATE, 'YYYYMM')和 MySQL 中DATE_FORMAT(CURRENT_DATE, '%Y%m') )。 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'.现在,您可以为此编写一个用户定义的函数 GET_CURRENT_MONTH_FORMATTED,它将返回当前月份的字符串,例如“202206”。 Then you'd have the different codes hidden in that function and the SQL queries would all look the same.然后,您将在该函数中隐藏不同的代码,并且 SQL 查询看起来都一样。 The problem, though, is how to tell the DBMS that the function result is deterministic for a particular timestamp?但是,问题是如何告诉 DBMS 函数结果对于特定时间戳是确定性的? 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'.如果您在 2022 年 12 月 31 日 23:50 运行查询,并且它一直运行到 2023 年 1 月 1 日 0:20,您希望 DBMS 只为导致“202212”的查询调用此函数一次并且不再被调用,突然导致另一个字符串'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.我认为您无法编写一个查询,该查询可以执行您想要的操作并且在所有提到的 DBMS 中看起来都一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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