3

我正在为 LibreOffice 中的一个非营利慈善机构建立一个会员数据库,但没有 mysql 查询方面的经验,因此我将不胜感激。

我正在尝试创建一个查询,该查询显示会员注册日期字段(PaymentDate)早于当前日期 1 年且另一个字段( AwaitingRenewal )的布尔值为NO的所有记录。日期采用05/03/85格式。感谢你给与我的帮助!

4

3 回答 3

7

您可以执行以下操作:

select * from `members` 
  where `paymentDate` < DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
  and `AwaitingRenewal` = 'NO'
于 2012-10-04T21:22:20.223 回答
1
* from dt_tb where `dt` >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
于 2012-10-05T01:31:17.757 回答
0

我的注意力被吸引到这个问题上,因为另一个类似的问题被关闭,引用这个问题是重复的。但我认为这些答案中的任何一个都不能完全解决这两个问题,所以我想补充一点我觉得缺失的一点。

当调用 MySQL或函数以分别获取当前日期或日期和时间时,一个DATEDATETIME列还没有携带时区信息,返回的值始终相对于当前有效的会话时区。所以有人要问,最初的列值是如何设置的?是通过调用还是如果是这样,当时有效的会话时区是否与现在有效的时区相同?或者,如果该列已使用诸如or之类的文字进行设置,那么setter 在创建该文字时会考虑什么隐式时区?同样,它是否与为当前会话设置的时区相同?CURDATENOWCURDATENOW'2020-03-01''2020-03-01 03:00:00'

只有当当前会话时区设置为与当前日期或日期和时间比较的列时显式或隐式有效的相同时区,MySQL 函数DATE_SUB才会为您提供正确的结果(或者,如果您知道这两个时区之间的小时差异,则可以调整DATE_SUB由该差异返回的结果)。

因此,如果您需要存储日期时间信息,以后您会问诸如此日期时间是否发生在一年多以前的问题,那么DATEIME列是一个糟糕的数据类型选择,因为它不包含时区信息. 如果此列类型被TIMESTAMP初始化为CURDATE()or NOW(),那么在内部数据将有效(尽管不完全)转换为 UTC 时间,因此将具有隐式 UTC 时区。随后,当该列与诸如 之类的函数进行比较或使用时CURDATE(),它将自动转换回对会话有效的当前时区,您将获得正确的结果。NOW()DATE_SUB

然而,在这个特定的例子中,我们正在处理一个DATE列。假设它是CURDATE()在使用默认会话时区(即America/Los_Angeles'. 一段时间后,您移至另一台服务器,现在当前默认会话时区为'America/New_York'. 如果您真的关心 3 小时的差异并希望尽可能准确(假设您意识到时区发生了这种变化),那么您需要设置正确的会话时区,该DATE列应该被解释为:

set session time_zone = 'America/Los_Angeles';
select * from `members` 
  where `paymentDate` < DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
  and `AwaitingRenewal` = 'NO'

或者一劳永逸地,您可以通过将paymentDate列转换为列来“修复”您的数据库TIMESTAMP(即使您只存储CURDATE()值,这些值将隐含00:00:00时间值):

set session time_zone = 'America/Los_Angeles';
alter table `members` change `paymentDate` `paymentDate` timestamp not null;

然后,您不必担心当前会话时区是什么,只要您将该paymentDate列与具有时区信息的值(例如由CURDATE()or返回)进行比较NOW()。但是您现在可能必须DATE对列使用该函数来抑制具有时间分量的结果,即使它是00:00:00

select * from `members` 
  where DATE(`paymentDate`) < DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
  and `AwaitingRenewal` = 'NO'

但是,如果您进行这种转换,还有一件事需要注意。列TIMESTAMP( pyamentDate) 将通过将内部值转换为当前会话时区来显示,而原始DATE列的显示完全独立于当前会话时区。

于 2021-03-11T13:50:13.663 回答