使用MySQL和PHP进行特定模式搜索 - 如何做到这一点?

时间:2018-03-21 16:29:58

标签: php mysql database search pattern-matching

我是MySQL和PHP的新手,所以我真的不知道如何做到这一点。我读了很多关于模式匹配的内容,但我不知道如何解决我的问题。

我在Column no中有一个包含特定代码的数据库。 1,以及列号中的代码的含义。这是一个例子:

+---------------+-----------+
| Code          | Meaning   |
+---------------+-----------+
| A5-B10-C11-D3 | object 1  | 
| A5-B10-C50-D8 | object 2  |
| A6-B10-C11-D7 | object 3  | 
| A2-B10-C11-D9 | object 4  |
| A5-B19-C11-D7 | object 5  | 
| A1-B10-C50-D8 | object 6  |
+---------------+-----------+

我想要做的是使用选项搜索,通过选择下一个模式来搜索第一列:

  • 从(X ...)开始 - 用户将键入A5,它将获得对象1,2和& 5
  • 以(... X)结尾 - 用户将键入D7,它将获得对象3& 5
  • 连续包含(X Y) - 用户将键入A5 B10,它将获得对象1& 2
  • 以任何顺序包含(X Y),但Y始终跟随X - 用户将键入B10 C11,它将获得对象1,3& 4,或B10 D8,它将获得对象2& 6
  • 包含两者,但没有顺序 - Y可以在X之前或之后 - 用户将键入D7 A5并且它将获得对象5.

一开始就足够了。当然,这些代码会更复杂 - 例如,B10-B10-A1-D15-C8,但搜索选项将涵盖所有模式。

提前谢谢你。如果我不清楚我想要什么,请告诉我,以便我可以进一步解释或提供更多的例子。

此外:

单独行中每个代码部分(A5,B10等)的解决方案对我不起作用。

在我的案例中,这将是更实际的解决方案:

 +-----------+-----------+-----------+-----------+-----------+
 | 1st place | 2nd place | 3rd place | 4th place | Meaning   |
 +-----------+-----------+-----------+-----------+-----------+
 | A5        | B10       | C11       | D3        | object 1  | 
 | A5        | B10       | C50       | D8        | object 2  |
 | A6        | B10       | C11       | D7        | object 3  | 
 | A2        | B10       | C11       | D9        | object 4  |
 | A5        | B19       | C11       | D7        | object 5  | 
 | A1        | B10       | C50       | D8        | object 6  |
 +-----------+-----------+-----------+-----------+-----------+

因此,例如代码A5-B10-C11-D3具有od对象1的含义。

因此,我的搜索将允许用户通过下一个方法进行搜索并获得后续结果:

  • 无订单:B10 - 结果:对象1,2,3,4,6
  • 开头:B10 - 结果:无。
  • 结束于:B10 - 结果:无。
  • 无订单:A5-B10(或A5 B10,不带破折号) - 结果:对象1,2
  • 开始于:A5-B10(或A5 B10,无破折号) - 结果:对象1,2
  • 结束于:A5-B10(或A5 B10,无破折号) - 结果:无。
  • 包含两者(X之后的Y,w / o或w /之间的其他字符)B10-C11(或B10 C11,不带破折号) - 结果:对象1,2,4。

可以这样做吗?

1 个答案:

答案 0 :(得分:3)

您可以使用LIKE进行大多数模式匹配。

  • 以:WHERE code LIKE 'A5-%'
  • 开头
  • 结束于:WHERE code LIKE '%-D7'
  • 连续包含:WHERE code LIKE '%A5-B10-%
  • 按顺序包含:WHERE code LIKE '%B10-%C11%'
  • 包含以下任一顺序:使用单个模式无法完成此操作,请使用ORWHERE code LIKE '%D7-%A5%' OR code LIKE '%A5-%D7%'

除了“以...开头”之外,由于它们无法使用索引,因此效率低下。如果您的代码具有有意义的结构,最好将它们拆分为单独的列,您可以明确搜索。

另一种选择是规范化你的数据,使每个部分都在另一个表的一个单独的行中,并带有一个外键。

Codes

Part_Num    Code    Meaning_ID
1           A5      1
2           B10     1
3           C11     1
4           D3      1
1           A5      2
2           B10     2
3           C50     2
4           D8      2

Meanings

ID  Meaning
1   object 1
2   object 2

然后您可以使用以下测试:

WHERE Part_Num = 1 AND Code = 'A5'
WHERE Part_Num = 4 AND Code = 'D7'

连续获取代码:

SELECT a.Meaning_ID
FROM Codes AS a
JOIN Codes AS b ON a.Meaning_ID = b.Meaning_ID AND a.Part_Num = b.Part_Num - 1
WHERE a.Code = 'A5' AND b.Code = 'B10';

对于有序的代码,但不是继承代码:

SELECT a.Meaning_ID
FROM Codes AS a
JOIN Codes AS b ON a.Meaning_ID = b.Meaning_ID AND a.Part_Num < b.Part_Num
WHERE a.Code = 'B10' AND b.Code = 'C11';

对于任何顺序的代码:

SELECT Meaning_ID
FROM Codes
WHERE Code IN ('D7', 'A5')
HAVING COUNT(*) = 2

使用新表将代码拆分为行的不同列,可以使用以下命令执行上一次查询:

WHERE 'D7' IN (1stPlace, 2ndPlace, 3rdPlace, 4thPlace) AND 'A5' IN (1stPlace, 2ndPlace, 3rdPlace, 4thPlace)