SQL 杂录: 如何模糊查询表里不存在的字段
1. 前提&场景
前提
表与需求都合理且不能更改。因此接下来我们就要根据需求与表结构实现一个较为特殊的模糊查询。
场景
要根据某个字段进行模糊查询, 但是这个字段是由若干个字段复合组成的,该字段在表中分为若干个字段存储,显示的时候拼接成一个字段。由于若干个字段复合略显复杂,因此接下来我们以2个字段举例:
举例
例如,我们某个编号,由前缀 prefix
与 自增数字 number
组成。一般情况下,我们直接从表里查prefix
与 number
,然后再拼接显示即可。但是,当前特殊情况下,当number
小于10时,为了对齐显示方便用户查看,需要在显示的时候在组合形成的字符串中补位补个"0",像这样:
prefix | number |
---|---|
A | 1 |
B | 20 |
通过这个表查出来的结果若直接拼接,将会是:
prefix | number | result |
---|---|---|
A | 1 | A1 |
B | 20 | B20 |
目标结果与实际显示应该是:
prefix | number | actual_result |
---|---|---|
A | 1 | A01 |
B | 20 | B20 |
实现这种显示,要么就要在查询的时候,直接查出来封装到VO中;要么就要分别查出让前端进行拼接。
毕竟,前提不能变嘛,表里没有冗余这两个字段拼接好的字段,无法直接模糊查询这个冗余字段。
那么问题来了,如何模糊查询这个可能随时在中间补位的字段呢?
2. 思路与解决方案
一般情况
一般情况下,我们直接查询,拼接即可。若后端封装的VO 存在该复合字段,则可以在查询的时候就用CONCAT
函数查询,例如
SELECT
*
FROM t1
WHERE CONCAT( prefix, number ) LIKE CONCAT('%', '0', '%')
这是一般中间没有补位的情况下这样查是比较方便的方式。
思路
一般遇到复合字段,两种思路:
- 先查后拼接:不增加额外开销,直接查询,查询完毕后,再交给前端拼接。这种方式对后端相对简单,对前端也提供了相对较大的样式调整灵活性。
- 查询时就拼接:通过聚合函数等方式,牺牲一点点 SQL 资源,在查询的时候就做好拼接,并能直接匹配查询条件。这种方式实际操作下来,最符合当前条件与需求。
- 业务上对查询条件进行过滤。效率最低、最麻烦的方法,类似于算法中的全排列算法,不到业务复杂到只能通过这种方法解决的地步决不用这个方法。
最终解决方案
聚合函数,通过聚合函数在查询时就实现拼接、匹配模糊字段。
以我们上文列举的两个字段复合并可能存在补位的情况为例:
SELECT
*,
IF(number < 10, CONCAT( prefix,'0', number ), CONCAT( prefix, number )) AS total
FROM
t1
WHERE
IF(number < 10, CONCAT( prefix,'0', number ), CONCAT( prefix, number )) LIKE CONCAT( '%', '0', '%' )
这样就解决了模糊查询查询数据库表中原本不存在的字段值。
3. 小结
对于遇到类似问题的朋友来说,以上方案可供参考。除了上文提到的参考方案,我们还可以根据不同的业务使用不同的聚合函数,以实现更多稍微特殊的查询,例如,在我解决问题的过程中,我的导师@Kievn就提到使用LOCATE()
函数对数字与字符串做进一步判断与处理,可适配更多的场景。
总的来说,方法总比困难多,只要需求合理,设计合理,我们就有办法实现,持续卷!