Yii2如何在where条件中调用函数处理字段实现日期比较?
Yii2中日期字段拆分比较的替代实现方案
首先得指出你原来代码里的问题:你写的exp('date1')是把字符串'date1'传给PHP的exp函数,而不是数据库中date1字段的实际值,这根本达不到你想要的效果,反而会把'date1'按/拆分,得到第一个元素'd',完全不符合需求。
下面给你几个正确的、更高效的实现方式,都是直接在数据库层面处理字段值:
方案1:用SUBSTRING_INDEX提取年份
利用MySQL的SUBSTRING_INDEX函数直接拆分date1字段,提取年份部分,再和date2的年份比较:
$promise = new ActiveDataProvider([ 'query' => Post::find() ->where(['status' => 'show']) ->andWhere(['<=', new \yii\db\Expression('SUBSTRING_INDEX(date1, "/", 1)'), new \yii\db\Expression('YEAR(date2)')]) ->orderBy('id'), ]);
这个函数会按/分割date1,取第一个部分(也就是年份),然后用YEAR(date2)提取date2的年份进行比较。
方案2:用LEFT函数直接取年份(更简洁)
因为你的date1格式是固定的YYYY/MM/DD,年份正好是前4个字符,用LEFT函数更直观:
$promise = new ActiveDataProvider([ 'query' => Post::find() ->where(['status' => 'show']) ->andWhere(['<=', new \yii\db\Expression('LEFT(date1, 4)'), new \yii\db\Expression('YEAR(date2)')]) ->orderBy('id'), ]);
方案3:转换为日期类型后完整比较(扩展性更强)
如果后续可能需要比较完整的日期(而不只是年份),建议把date1字符串转换为数据库的DATE类型,这样就能直接和date2(假设是DATE/DATETIME类型)做完整日期比较:
$promise = new ActiveDataProvider([ 'query' => Post::find() ->where(['status' => 'show']) ->andWhere(['<=', new \yii\db\Expression('STR_TO_DATE(date1, "%Y/%m/%d")'), 'date2']) ->orderBy('id'), ]);
STR_TO_DATE会把YYYY/MM/DD格式的字符串转换成DATE类型,这样就能直接和date2进行<=的日期比较,不管是年份、月份还是日期都能正确判断。
这些方案的优势在于所有处理都在数据库端完成,不需要把数据拉到PHP层面再处理,效率更高,也能正确作用于每一条数据的字段值。
内容的提问来源于stack exchange,提问作者Mohammad Aghayari
相关产品推荐
相关产品推荐

