MySQL WHERE - 通配符“忽略”选项?

时间:2015-08-20 15:13:48

标签: php mysql wildcard

由于遗留设计问题,我试图找出解决此问题的最有效方法。使用包含两个字段的TABLE: program Want2D integer :: a(6,5), b(2) a = reshape( (/ (i , i = 1, size(a) ) /) , shape(a) ) b = (/ 5 , 3 /) write(*,*) a(b) end program Want2D 其中“pk”是主键,但也用于查找的文档编号。

我从用户收到的数据可能是整数,也可能是整数之前的项目组合。例如:

用户来自的文档编号:pk int(10), year timestamp 因此,从2015年开始,主键为1025的示例表格将是 FM15-A1025

使用AJAX,用户可以搜索以下任何内容以查找此(和其他)表单:

F
FM
FM1
FM15
FM15-
FM15-A
FM15-A1
FM15-A10
FM15-A102
FM15-A1025

我的问题是,如果使用MySQL和PHP的组合,我可以返回适用于此搜索的所有PK值吗?显然,“F”和“FM”将返回所有值,但2015年的年度组件将给出与2020年不同的答案。

我不知道MySQL通配符或方法允许您在搜索中忽略部分列,并且有很多PHP(在此过程中使用大量CPU /内存)这个简单的外观-up。目前,我的PHP完成了工作,但对于这么简单的任务来说,它非常复杂:

"FM" + Last two digits of the year + "-A" + pk.

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我建议制作一个SQL视图,让您的生活更轻松。

CREATE VIEW DocumentIdView AS
SELECT CONCAT('FM', DATE_FORMAT(year,'%y'), '-A', pk) AS docId, pk FROM table

然后在你的PHP代码中,你可以做一个

SELECT b.* FROM DocumentIdView a LEFT JOIN table b ON a.pk = b.pk WHERE a.docId LIKE 'FM15-A1%'

显然,如果你不想拥有SQL视图,你可以将两个选择结合起来。

SELECT * FROM (SELECT CONCAT('FM', DATE_FORMAT(year,'%y'), '-A', pk) AS docId, pk FROM table) a LEFT JOIN table b ON a.pk = b.pk WHERE a.docId LIKE 'FM15-A1%'

如果这不能很好地执行,我建议将文档ID作为列存储在表中以便快速查找。或者,如果不能更新表格,请为@rlanvin建议的查询创建materialized view

答案 1 :(得分:1)

使用允许LIKE通配符的MySQL字符串 - 运算符%,您可以拆分字符串并优化搜索标准。

$sql_where = "";
$search = "FM15-A1025";

if (strlen($search) >= 3) {
    $y = int(substr($search, 2, 2));
    $sql_where .= "DATE_FORMAT(year,'%y') LIKE '$y%'";
}
if (strlen($search) >= 7) {
    $pk = int(substr($search, 6));
    $sql_where .= " AND CAST(pk as char) LIKE '$pk%'";
}

请注意,LIKE的性能不佳,如果你不注意避免SQL注入,那么将SQL-Strings粘合在一起会很危险