如何理解这条Mysql模糊查询语句
select * from `user` where username like "%" 'name' "%"(可以查出数据)
select * from `user` where username like "%" "name" "%"(查不出来数据)
我不太理解这两种写法字符串的拼接结果是什么
如何理解这条Mysql模糊查询语句
select * from `user` where username like "%" 'name' "%"(可以查出数据)
select * from `user` where username like "%" "name" "%"(查不出来数据)
我不太理解这两种写法字符串的拼接结果是什么
连着写的引号括起的字符串会合成一个,
以上两种写法都能返回数据:
select username,2 from user where username like "%" "test" "%";
返回:
username | 2 |
test123 | 2 |
使用单引号 '
和双引号 "
的区别如下:
单引号 '
:
'
需要使用转义字符 ''
来表示。双引号 "
:
在这两个查询中:
select * from user where username like "%" 'name' "%"
:
'
包裹 name
。select * from user where username like "%" "name" "%"
:
"
包裹 name
。第一个查询可以查出数据,而第二个查询查不出数据
因为用户名中可能没有严格包含 "name" 的情况。
语法层面的,已经有回答解释过了,这是补充一下查询部分的。
你既然没有说 MySQL 版本,那我就只好用较新版本的 MySQL 来测,使用 explain 后再执行 show warnings;
可以看到 MySQL 处理后的语句,可以看到这两个的查询最终的 SQL 筛选部分都是一样的,而我这里执行也符合预期,两个查询都查到了数据,而不是你原题中说的那样。
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.30 |
+-----------+
1 row in set (0.00 sec)
mysql> explain select name from fake_person where name like "%" "米" "%";
+----+-------------+-------------+------------+-------+---------------+----------+---------+------+---------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+-------+---------------+----------+---------+------+---------+----------+--------------------------+
| 1 | SIMPLE | fake_person | NULL | index | NULL | idx_name | 51 | NULL | 1955381 | 11.11 | Using where; Using index |
+----+-------------+-------------+------------+-------+---------------+----------+---------+------+---------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message
|
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `big_data`.`fake_person`.`name` AS `name` from `big_data`.`fake_person` where (`big_data`.`fake_person`.`name` like '%米%') |
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> explain select name from fake_person where name like "%" '米' "%";
+----+-------------+-------------+------------+-------+---------------+----------+---------+------+---------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+-------+---------------+----------+---------+------+---------+----------+--------------------------+
| 1 | SIMPLE | fake_person | NULL | index | NULL | idx_name | 51 | NULL | 1955381 | 11.11 | Using where; Using index |
+----+-------------+-------------+------------+-------+---------------+----------+---------+------+---------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message
|
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `big_data`.`fake_person`.`name` AS `name` from `big_data`.`fake_person` where (`big_data`.`fake_person`.`name` like '%米%') |
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
或者在 MySQL 8 以上使用 explain analyze
也可以看到筛选部分都是一致的。
mysql> explain analyze select name from fake_person where name like "%" '米' "%";
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Filter: (fake_person.`name` like '%米%') (cost=234625.68 rows=217243) (actual time=275.600..517.165 rows=6606 loops=1)
-> Covering index scan on fake_person using idx_name (cost=234625.68 rows=1955381) (actual time=0.058..328.245 rows=2000000 loops=1)
|
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.52 sec)
mysql> explain analyze select name from fake_person where name like "%" "米" "%";
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Filter: (fake_person.`name` like '%米%') (cost=234625.68 rows=217243) (actual time=342.288..558.971 rows=6606 loops=1)
-> Covering index scan on fake_person using idx_name (cost=234625.68 rows=1955381) (actual time=0.025..346.099 rows=2000000 loops=1)
|
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.56 sec)
最后亦或者使用 Optimizer Trace 这两条 SQL 得到的筛选也是一样的。
4 回答950 阅读✓ 已解决
8 回答1.1k 阅读
3 回答972 阅读✓ 已解决
2 回答1.6k 阅读
1 回答810 阅读✓ 已解决
2 回答989 阅读
1 回答603 阅读✓ 已解决
楼上说的只有在各个字符串之间使用空格作分隔时,这几个字符串才会连接起来(相当于like '%name%'),题目里的示例第一个查得出来数据而第二个查不出来,我试了下是没有用空格作分隔的情况。(如果用了空格则和楼上的回答一样两个都可以查得出来,见我截的官方文档里的示例),猜测是解析的时候用了某种转义再拼接?

话说回来官方的用法里并没有也不推荐用题目里的写法,如果要研究MYSQL是怎么处理这样的情况的话可以了解,正式使用的时候还是老老实实使用官方的示例和推荐的用法吧,比如CONCAT函数、CONCAT_WS函数以及这种字符串之间使用空格并排的用法。