Mysql日期为VARCHAR类型,可以直接比较吗

表t1
列c1 varchar 且格式与20130529这种格式相同.
1.直接比较
select * from t1 where c1 <= '20130529';
2.用函数转为date后再比较
select * from t1 where str_to_date(c1, '%Y%m%d') <= str_to_date('20130529', '%Y%m%d');

目前倾向于直接用第一种,因为建了索引,但是怕会出错,所以想请教大家两种写法哪种更好?

这两个写法有各自的优缺点:

  1. 直接比较:
    优点:
  • 如果c1有索引,查询性能会更高
    缺点:
  • c1的格式必须严格匹配'%Y%m%d',否则会导致错误结果
  • 不够灵活,如果格式变化需要修改代码
  1. 使用函数转换为DATE比较:
    优点:
  • 可以处理c1格式不统一的情况,更加灵活和安全
    缺点:
  • 如果转换过程中产生临时表,查询性能会受到影响所以,总体来说:如果c1的格式确定并统一为'%Y%m%d'且有索引,那么直接比较操作会更高效。
    如果c1的格式不确定或存在变化,使用DATE函数转换后比较,可以确保结果正确性,更加灵活。
    那么您的场景中,c1的格式是确定的'%Y%m%d',并且有索引,所以我的建议是:优先使用直接比较的方式:
select * from t1 where c1 <= '20130529'; 

这可以获得最高的查询性能。但是,为了避免c1格式在未来有变动导致错误,您也可以考虑:
在开发环境/测试环境中使用DATE函数验证:

select * from t1 where str_to_date(c1, '%Y%m%d') <= str_to_date('20130529', '%Y%m%d');

在确认结果正确性后,再在生产环境中使用直接比较,获得最佳性能。这种方式可以在灵活性和性能之间取得一个平衡。

可以是可以比较的,但是结果可能会有偏差的,个人建议你使用第二种

可以,但是字符串比较速度会慢

两种都不是什么好办法
数据库里字段类型就应该直接用date而不是varchar
date类型不仅可以保证你输入的时候必定是个有效的日期,而且它是数值类型,存储空间也有优势
比较的时候也快

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7771424
  • 以下回答来自chatgpt:

    对于问题中的日期比较,建议将日期字符串转换为日期格式后再进行比较,避免出现错误。可以使用SimpleDateFormat类进行日期格式转换,具体步骤如下:

    1. 创建SimpleDateFormat对象,将日期格式作为参数传入。例如,如果日期格式为"yyyyMMdd",则可以创建如下对象:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

    1. 使用SimpleDateFormat对象的parse方法将日期字符串转换为Date对象。例如,如果日期字符串为"20130529",则可以通过如下代码将其转换为Date对象:

    Date date = sdf.parse("20130529");

    1. 将转换后的两个Date对象进行比较,可以使用Date类的before、after、compareTo等方法进行比较。

    具体实现可以参考以下代码:

    // 初始化SimpleDateFormat对象,指定日期格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

    // 从数据库获取日期字符串 String dateStr = "20130528";

    // 将日期字符串转换为Date对象 Date date1 = sdf.parse(dateStr);

    // 创建另一个日期字符串 String dateStr2 = "20130601";

    // 将日期字符串转换为Date对象 Date date2 = sdf.parse(dateStr2);

    // 比较两个日期对象 if(date1.before(date2)){ System.out.println(dateStr + " is before " + dateStr2); } else { System.out.println(dateStr + " is not before " + dateStr2); }

    代码执行结果为"20130528 is before 20130601",说明比较成功。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^