如果我需要搜索没有小时和分钟存储的出生日期,但我必须搜索的日期包括小时和分钟,那么返回所有日期仅在日、月和年匹配的行的最佳方法是什么
即
存储为 01-JAN-50 10.22.06.000000000
日期选择 01-JAN-50 10.22.06.010101120
如果我将日期与小时和分钟一起使用,SQL 将只返回具有确切时间戳的行,而不是仅返回日、月和年的行。
SQL 需要在 Oracle、SQLServer、MySQL 和 DB2 上运行。
如果我需要搜索没有小时和分钟存储的出生日期,但我必须搜索的日期包括小时和分钟,那么返回所有日期仅在日、月和年匹配的行的最佳方法是什么
即
存储为 01-JAN-50 10.22.06.000000000
日期选择 01-JAN-50 10.22.06.010101120
如果我将日期与小时和分钟一起使用,SQL 将只返回具有确切时间戳的行,而不是仅返回日、月和年的行。
SQL 需要在 Oracle、SQLServer、MySQL 和 DB2 上运行。
Oracle 的 DATE 类型早于 SQL 标准版本(Informix 的版本也是如此),这使得以 DBMS 中立的方式执行此操作非常困难(如果不是不可能的话)。当然,还有一个问题是“为什么选择的数据表示包括时间”。
在标准 SQL 中,显而易见的技术是将 TIMESTAMP 转换为 DATE。对于您必须搜索的数据,我们也没有明确的解释。
SELECT CAST(DateOfBirth AS DATE), ...other columns...
FROM TheMysteryTable -- Why do people hate giving tables names?
WHERE CAST(DateOfBirth AS DATE) =
CAST(TIMESTAMP '1950-01-01 10.22.06.010101120' AS DATE)
但这假设您将“搜索日期”写为文字。如果是宿主变量,那么宿主变量的类型应该是 DATE,而不是 TIMESTAMP。DateOfBirth 列可能应该是 DATE,而不是 TIMESTAMP。除非时间部分相关,否则不应使用 TIMESTAMP - 它会浪费存储空间并浪费计算时间。
请注意,由于强制转换,DBMS 不太可能使用任何索引或任何东西。如果类型是健全的,那么查询将很简单:
SELECT DateOfBirth, ...other columns...
FROM TheMysteryTable
WHERE DateOfBirth = DATE '1950-01-01'
由于任何解决方案都需要操作日期和日期时间对象,因此不会有与系统无关的解决方案——每个解决方案对于这些对象都有不同的功能。
除了数据库抽象之外,最好的解决方案是先对正在使用的日期时间对象进行四舍五入,然后只需要一个通用的 SQL 比较子句,该子句在所有列出的数据库中都可以使用。
没有 ANSI 日期格式,也没有字符串操作。任何代码都只能在某些 RDBMS 中运行,如果不是只有一个的话。
但是,如果您在 RDBMS 之外获取所选日期(例如 PHP、Java 等),我建议在将其发送到查询之前对其进行清理;然后您可以将字符串与字符串进行比较,这几乎适用于所有系统。
正如其他人所指出的,RDBMS 在处理日期时间方面非常不同。如果他们实际上遵循 ANSI-92 标准,那么以下应该有效:
SELECT
<column list>
FROM
<table name>
WHERE
CAST(birth_date AS DATE) = CAST(search_date AS DATE)
不过,这并不是最有效的方法,因为它会排除在大多数系统上使用日期索引。以下可能适用于完全符合 ANSI-92 的数据库:
SELECT
<column list>
FROM
<table name>
WHERE
birth_date >= CAST(CAST(search_date AS DATE) AS DATETIME) AND
birth_date < CAST(CAST(search_date AS DATE) + 1 AS DATETIME)
使用 EXTRACT()