【问题标题】:DATETIME vs LIKE to make a dynamic search SQLDATETIME vs LIKE 进行动态搜索 SQL
【发布时间】:2016-05-13 12:05:25
【问题描述】:

我想根据我的 $data 输入在我的数据库中动态搜索一个日期。

日期存储为日期时间,通常显示为例如:“2016-05-11”。

对于 MySql DB,我的子句是:

Select * From Table WHERE ( Table.date LIKE '$data%' ) 

因此,如果用户输入“20”,结果将是所有以 20 开头的日期。如果用户输入“2016-05”,结果将是所有以 2016-05 开头的日期,使我的搜索完美运行。

在 Sql Server 2008 上进行部署时,我意识到了两件事。

1) 如果我像这样使用 LIKE 函数

Select * From Table WHERE ( Table.date LIKE '%$data$%') 

该函数适用于值 "2016" ,但输入值 "2016-" 时将返回 0 个结果。

2) 如果我这样使用函数 DATETIME

Select * From Table WHERE ( DATEPART(year, Table.date) LIKE(OR)= '$data') 

函数将在 $data = 2016 时返回正确的值,但在 $data = '201' 时返回 nil 值,因此它不是动态的。

我做错了什么?

【问题讨论】:

  • 问题出在输入验证上。如果用户可以输入20,他们也可以输入'fred2016-02-30
  • 我正在使用 ajax 调用,所以如果他们进入 Fred。他们不会得到结果。那不是问题吗?我说的不对吗?

标签: mysql sql sql-server-2008


【解决方案1】:

在 SQL 或大多数其他编程语言中,隐式转换是糟糕的、糟糕的、糟糕的。

LIKE 作用于字符串。如果你想让它在字符串上工作,那么明确确保参数是字符串。在 MySQL 和 SQL Server 中也是如此。

如果你想在年份使用LIKE,那么使用DATENAME()而不是DATEPART()

WHERE DATENAME(year, Table.date) LIKE '$data'

但是,我建议您考虑使用基于日期的结构来考虑日期,例如日期范围。

【讨论】:

  • 但是,我的输入是一个字符串!我明确告诉用户输入一个 YYYY-MM-DD 字符串,然后我的搜索就会相应地发生。所以这不是问题!?
  • 几乎所有按日期搜索的应用程序都使用日期范围。即使您以某种方式想出了一种更好的方法来搜索其他人从未想到过的日期(怀疑),这也是人们所期望的。当我去航空公司预订网站并想按日期搜索时,我不希望输入“2016-06-”来搜索 6 月的航班。另外,如何搜索 2016-05-18 和 2016-05-21 之间的日期?
  • @MakDo 。 . .然后使用date_format()convert() 将日期值显式 转换为字符串。顺便说一句,所有这些方法都排除了索引的使用——隐式转换和函数调用通常会干扰索引的使用。
  • 这样,您将无法将日期信息用于“单值”搜索以外的任何用途。例如任何缺少基于日期的聚合分析或子集
  • @TomH。我在问。从来没有说过我创造了没有人想过的东西。而不是你的自我评论。编码做什么会更好。
【解决方案2】:

我刚刚意识到我的愚蠢错误。 我需要使用 DATEPART 将通配符添加到我的 LIKE 子句中。

Select * From Table WHERE (DATEPART(year, Table.date) LIKE = '$data%')。

完美运行。

但我希望有其他建议可以简化将 $data 拆分为 YYYY 、 MM 、 DD 然后测试每个元素的过程。

【讨论】:

    【解决方案3】:

    我会努力保持Table.date 不受操纵,因此使用索引。

    相反,您可以使用CASE 表达式通过添加缺失部分将搜索参数转换为日期范围:

    下限:

    CASE LENGTH($data) 
     WHEN 8 THEN $data + '01'
     WHEN 7 THEN $data + '-01'
     WHEN 5 THEN $data + '01-01'
     WHEN 4 THEN $data + '-01-01'
     ELSE $data
    END
    

    上限:

    CASE LENGTH($data) 
     WHEN 8 THEN DATEADD(MONTH,$data + '01',1)
     WHEN 7 THEN DATEADD(MONTH,$data + '-01',1)
     WHEN 5 THEN DATEADD(YEAR,$data + '01-01')
     WHEN 4 THEN DATEADD(YEAR,$data + '-01-01')
     ELSE DATEADD(DAY,$data,1)
    END
    

    【讨论】:

      猜你喜欢
      • 2015-04-30
      • 2017-06-23
      • 2014-02-10
      • 2011-08-03
      • 2013-03-14
      • 2014-10-14
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多