如何编写通用 SQL 查询以与所有 RDBMS(Oracle、SQL 服务器、MySql、DB2 等等)兼容的 (YYYY-MM-DD) 形式提取日期

Posted

技术标签:

【中文标题】如何编写通用 SQL 查询以与所有 RDBMS(Oracle、SQL 服务器、MySql、DB2 等等)兼容的 (YYYY-MM-DD) 形式提取日期【英文标题】:How to write a generic SQL query to extract date in (YYYY-MM-DD) form which is compatible with all RDBMS (Oracle, SQL server, MySql, DB2 to name few) 【发布时间】:2021-04-11 22:14:33 【问题描述】:

我有一个插入学生记录的表,并且有一个名为joined_date 的列,它在SQL Server 中的类型为datetime2,在Oracle 中为TIMESTAMP(6)。我需要检索在特定日期加入的学生人数,因此我需要按joined_date 分组。为此,我只需要从 joined_date 列中提取日期 (YYYY-MM-DD),它应该是一个通用 SQL 查询。

查询:select joined_date, count(*) from student group by joined_date

我可以在 Oracle 中使用TO_CHAR(joined_date, 'YYYY-MM-DD') AS joined_date

类似地,我们可以在 SQL Server 中使用它自己的转换函数进行转换。但我需要一个与数据库无关的通用查询。

【问题讨论】:

您使用哪个客户端?通常,您可以简单地将 date(!) 值传递到查询中,驱动程序(例如 ODBC 驱动程序)会处理所有事情。通常不需要将其转换为字符串。 我正在使用带有纯 sql 的 jdbcTemplate 在我的 Spring Boot 应用程序中呈现数据。同意,我不需要将其转换为字符串,但我只需要从 timestamp/datetime2 列中提取日期。 不幸的是,如果您无法对数据库系统供应商产生影响,以至于您可以要求他们实际上同意统一其日期操作功能,您将不会获得与数据库无关的查询。跨度> 在 SQL 标准中,您将使用 cast(joined_date as date) 如果列表示日期,为什么使用 datetime2 而不是 date? MS 和 Oracle 都支持这些,并且这种简单的更改似乎可以解决您所说的问题。但它也可以防止 MS 方面的未来问题,其中列中的值的时间部分不是“00:00:00 ...”(大概这是你的假设)。在这种情况下,您的分组将不会产生正确的计数。 【参考方案1】:

或多或少,每个数据库都有自己的功能来完成类似的工作。我不确定您是否可以使用单个查询来做您想做的事情。

但是,如果您在每个数据库中创建了一个视图,并以相同的格式提取所需的值 - 例如,在 Oracle 中

create or replace view v_student as
  select student_id,
         student_name,
         to_char(joined_date, 'yyyy-mm-dd') joined_date
  from student;

那么您将在所有这些数据库中运行相同的查询:

select joined_date,
       count(*)
from v_student
group by joined_date;

select student_name
from v_student
where joined_date = '2020-09-01'  --> this is a string!!!
order by student_name;

当然,这“解决”了这个特定问题。日期算术会很困难,因为日期现在表示为字符串,但是 - 这就是您所要求的。

看看有没有帮助。

【讨论】:

以上是关于如何编写通用 SQL 查询以与所有 RDBMS(Oracle、SQL 服务器、MySql、DB2 等等)兼容的 (YYYY-MM-DD) 形式提取日期的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 RDBMS 中为每个呼叫客户的 CDR(呼叫数据记录)编写 sql 查询。?

创建 C++ 应用程序以与 Nginx 通信的最佳方法

T-SQL快速指南

T-SQL:如何将逗号连接到除最终记录之外的所有文本字段

数据库牛人是如何进行SQL优化的?

如何在不使用 CURDATE、MONTH、YEAR 等 DATE 函数的情况下从 RDBMS 获取当前月份记录