如何编写通用 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) 形式提取日期的主要内容,如果未能解决你的问题,请参考以下文章