TiDB查询date类型数据时无结果,使用cast(? as DATE)解决

86 篇文章 0 订阅
1 篇文章 0 订阅

摘要

错误使用的例子:

todayZeroTime, _ := time.Parse("2006-01-02", time.Now().Format("2006-01-02"))
db = db.Where("(start_at = ? || end_at = ?)", todayZeroTime, todayZeroTime.AddDate(0, 0, -1))

例子修改如下:

db = db.Where("(start_at = cast(? as DATE) || end_at = cast(? as DATE))", time.Now(), time.Now().AddDate(0, 0, -1))

问题起因

TiDB某条记录有date字段字段,值例如为2020.09.14,sql直接使用:

SELECT * FROM `rule_tag_ele_num`  WHERE `rule_tag_ele_num`.`deleted_at` IS NULL AND ((tag_id = 1 AND date BETWEEN '2020-09-14 00:00:00' AND '2020-09-16 00:00:00'))

查询的话,2020.09.14这条记录就不会返回,但是mysql是可以的,但是TiDB声称完全兼容mysql,所以是不是因为我between用的话不规范的问题,对TiDB和mysql都不规范,但是这种不规范被mysql漫长的版本迭代中给容错掉了,遂查mysql官方文档的标准推荐用法

mysql官方文档

https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between

expr BETWEEN min AND max

If expr is greater than or equal to min and expr is less than or equal to maxBETWEEN returns 1, otherwise it returns 0. This is equivalent to the expression (min <= expr AND expr <= max) if all the arguments are of the same type. Otherwise type conversion takes place according to the rules described in Section 12.3, “Type Conversion in Expression Evaluation”, but applied to all the three arguments.

mysql> SELECT 2 BETWEEN 1 AND 3, 2 BETWEEN 3 and 1;
        -> 1, 0
mysql> SELECT 1 BETWEEN 2 AND 3;
        -> 0
mysql> SELECT 'b' BETWEEN 'a' AND 'c';
        -> 1
mysql> SELECT 2 BETWEEN 2 AND '3';
        -> 1
mysql> SELECT 2 BETWEEN 2 AND 'x-3';
        -> 0

For best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type. Examples: If you compare a DATETIME to two DATE values, convert the DATE values to DATETIME values. If you use a string constant such as '2001-1-1' in a comparison to a DATE, cast the string to a DATE.

果然,其中的:

For best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.

给出了明确的建议。

修改后的sql

("SELECT * FROM `extension_tag_num`  WHERE `extension_tag_num`.`deleted_at` IS NULL AND ((basic_id = ? AND date BETWEEN cast(? as DATE) AND cast(? as DATE)))", tagId, dateStart, dateEnd)

此时unit test在mysql和TiDB的执行都pass了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据查询中,cast as date是将字符串类型转换为日期类型的一种方法。这种方法可以将一个字符串表示的日期转换为数据库中的日期数据类型。在引用中的示例中,使用cast('25-1月 -19' as date)将字符串'25-1月 -19'转换为日期类型。同样地,在引用中的示例中,使用cast(sysdate as varchar2(100))将日期类型转换为字符串类型。 在引用中的示例中,使用cast(? as DATE)将间戳转换为日期类型。这段代码中的?表示间戳的参数,通过cast函数将其转换为日期类型以进行数据查询。这种方法可以用于比较日期范围,例如查询某个范围内的数据。 总结起来,cast as date是一种将字符串或间戳转换为日期类型的方法,可以在数据查询使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [oracle的函数cast进行类型转换用法](https://blog.csdn.net/gc1329689056/article/details/91879628)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [TiDB查询date类型数据无结果,使用cast(? as DATE)解决](https://blog.csdn.net/chushoufengli/article/details/108642663)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值