Mysql使用exist和not exist的场景举例

博客主要介绍了SQL中使用EXISTS的几种情况,包括用EXISTS替换IN、替换查询子句、代替COUNT判断条件数据是否存在,以及使用NOT EXISTS查询父结果集有而子结果集没有的记录,还提及3条SQL性能依次降低。

例1:用exists替换in

select num from a where num in(select num from b) 

替换为

select num from a where exists(select 1 from b where num=a.num)

例2:用exists替换查询子句

SELECT SUM(T1.C1) FROM T1 WHERE (SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2)>0

替换为

SELECT SUM(T1.C1) FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)

例3:用exists代替count判断是否存在某种条件数据

IF (SELECT COUNT(*) FROM table_name WHERE column_name = 'xxx')

替换为

IF EXISTS (SELECT * FROM table_name WHERE column_name = 'xxx')

例4:查询父结果集中有而子结果集中没有的记录(not exists)

以下3条sql性能依次降低

SELECT a.hdr_key FROM hdr_tbl a WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)
SELECT a.hdr_key FROM hdr_tbl a LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL
SELECT hdr_key FROM hdr_tbl WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)
<think>我们面临的问题是:执行 `alter table is_SB change name isSB text;` 时出现错误 `ERROR 1146 (42S02): Table 'liuyumeng.is_sb' doesn't exist`。 错误信息表明:在数据库`liuyumeng`中,表`is_sb`不存在(MySQL表名在Linux系统下默认是大小写敏感的,但实际存储的表名可能是区分大小写的,也可能不区分,取决于系统配置)。 根据引用[1][3]中的错误(表不存在)以及引用[4]中关于表名大小写的解决方案,我们可以推测: 1. 表名在数据库中可能是区分大小写的(例如,在Linux系统中,MySQL默认使用区分大小写的表名存储)。 2. 我们执行的语句中,表名`is_SB`(注意有下划线)与数据库中实际存储的表名不一致(可能是大小写不一致,或者表名实际是`is_sb`?)。 让我们分析: - 错误提示的表名是`liuyumeng.is_sb`(全部小写,并且单词之间用下划线连接)。而我们的语句中表名是`is_SB`(大写字母SB)。 - 在MySQL中,表名的大小写处理取决于操作系统MySQL的配置。在Linux下,默认是大小写敏感的,因此`is_SB``is_sb`是不同的表。 因此,可能的原因: 1. 表名在数据库中实际上是`is_sb`(小写),而我们试图操作`is_SB`(大写),所以认为表不存在。 2. 或者,表名在数据库中确实是`is_SB`(带有大写),但配置了表名存储为小写(例如,配置了`lower_case_table_names=1`),那么MySQL会将表名转换为小写来存储,但在查询时也要求使用小写。 解决方案步骤: 步骤1:确认表是否存在 我们可以先查看数据库中是否存在名为`is_SB`或`is_sb`的表: ```sql SHOW TABLES LIKE 'is_sb'; SHOW TABLES LIKE 'is_SB'; ``` 或者,查看所有表名: ```sql SHOW TABLES; ``` 注意:在MySQL客户端中执行时,注意表名的大小写。 步骤2:根据实际表名修改语句 如果表实际名称是`is_sb`(小写),那么应该使用: ```sql alter table is_sb change name isSB text; ``` 如果表实际名称是`is_SB`(保留大写),那么确保在大小写敏感的环境下写对表名。 步骤3:检查MySQL的大小写配置 我们可以通过以下命令查看MySQL的大小写敏感配置: ```sql SHOW VARIABLES LIKE 'lower_case_table_names'; ``` 该变量的含义: - 0:表名存储为给定的大小写,比较时大小写敏感(Linux默认)。 - 1:表名存储为小写,比较时大小写不敏感(Windows默认,MacOS默认)。 - 2:表名存储为给定的大小写,但比较时会转换成小写(只在不区分大小写的文件系统上适用)。 如果配置是1(不区分大小写),那么无论我们写`is_sb`还是`is_SB`,MySQL都会将其转换为小写,所以表名必须用小写。 步骤4:修改表名(如果确实写错) 如果发现表名确实写错了(比如应该是`is_sb`),但创建表时用了其他大小写形式,我们可以通过重命名表来避免后续问题: ```sql RENAME TABLE `is_SB` TO `is_sb`; -- 假设原表名是`is_SB`,现在改为小写 ``` 注意:重命名操作需要表存在。 步骤5:如果表确实不存在,那么需要先创建表 如果发现表根本不存在,那么需要先创建表。创建表的语句类似: ```sql CREATE TABLE is_sb ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) ); ``` 然后再执行alter语句。 根据引用[4]中的解决方案,有时在连接字符串中设置参数可以解决表名大小写问题(如`nullCatalogMeansCurrent=true`),但这是在Java连接数据库使用的参数,用于指定当前数据库的schema。但我们的问题是在直接执行SQL语句时出现的,所以这个设置不适用。 总结解决方案: 1. 首先确认表是否存在,使用`SHOW TABLES`查看。 2. 如果表存在,则检查表名的大小写是否与语句中的一致。如果不一致,修改语句中的表名为实际表名。 3. 检查`lower_case_table_names`配置,根据配置调整表名的大小写使用习惯。 4. 如果表不存在,创建表后再执行alter语句。 注意:在MySQL中,对于表名列名,可以使用反引号(`)来避免关键字冲突,也可以明确指定大小写,例如: ```sql alter table `is_SB` change `name` `isSB` text; ``` 但是,如果数据库配置为不区分大小写(`lower_case_table_names=1`),那么即使使用反引号指定大写,也会被转换为小写存储比较。 因此,请根据实际情况调整表名。 举例: 假设我们执行`SHOW TABLES`后看到表名是`is_sb`(小写),那么正确的语句是: ```sql alter table is_sb change name isSB text; ``` 如果表名是`is_SB`(大写),那么语句应该是: ```sql alter table is_SB change name isSB text; ``` 但是,如果配置了`lower_case_table_names=1`,那么即使我们写`is_SB`,也会被当作`is_sb`,所以建议在这种情况下统一使用小写表名。 如果问题依然存在,请提供以下信息: - 执行`SHOW TABLES`的结果。 - 执行`SHOW VARIABLES LIKE 'lower_case_table_names';`的结果。 这样我们可以更准确地定位问题。 相关问题: 1. 如何修改MySQL表名的大小写敏感性? 2. 在MySQL中,如何避免因表名大小写导致的错误? 3. MySQL中表名大小写敏感有哪些配置方式? </think>### 解决 "ERROR 1146 (42S02): Table 'liuyumeng.is_sb' doesn't exist" 错误 此错误表明 MySQL 无法找到要修改的表。结合引用内容[1][3][4]的类似案例,以下是分步解决方案: --- ### 1. **确认表名大小写(关键步骤)** MySQL 在 Linux 系统中默认**区分表名大小写**(Windows/Mac 不区分)。执行以下命令验证表名: ```sql -- 查看当前数据库所有表(注意大小写) SHOW TABLES; -- 模糊查询包含"is_sb"的表 SHOW TABLES LIKE '%is_sb%'; ``` - 如果显示表名为 `is_SB`(含大写),则需在 SQL 语句中保持相同大小写: ```sql ALTER TABLE `is_SB` CHANGE name isSB TEXT; -- 使用反引号包裹表名 ``` - 如果不存在 `is_SB` 或 `is_sb`,跳转到第3步。 --- ### 2. **检查数据库上下文** 错误中的 `liuyumeng.is_sb` 表明: - 当前数据库是否为 `liuyumeng`? - 表是否在其他数据库中? 验证方法: ```sql -- 查看当前使用数据库 SELECT DATABASE(); -- 若需切换数据库 USE liuyumeng; -- 或显式指定数据库(推荐) ALTER TABLE `liuyumeng`.`is_SB` CHANGE name isSB TEXT; ``` --- ### 3. **处理表不存在的情况** 如果表确实不存在(引用[3][4]类似场景): - **方案1:手动创建表** 先创建表结构再执行修改: ```sql CREATE TABLE is_SB ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) -- 根据实际需求定义字段 ); ALTER TABLE is_SB CHANGE name isSB TEXT; ``` - **方案2:检查自动建表配置**(参考引用[4]) 如果是框架(如 Flowable)自动管理表结构: 1. 在连接字符串添加 `nullCatalogMeansCurrent=true`: ```yaml url: jdbc:mysql://localhost:3306/liuyumeng?nullCatalogMeansCurrent=true ``` 2. 启用自动更新表结构: ```yaml flowable: database-schema-update: true # Spring Boot 配置示例 ``` --- ### 4. **验证表状态** 排除表损坏或元数据错误: ```sql -- 检查表状态 CHECK TABLE is_SB; -- 刷新表缓存(适用表结构刚变动) FLUSH TABLES; ``` --- ### 5. **系统级配置检查** - **大小写敏感配置**(引用[1][4]): 在 MySQL 配置文件 `/etc/my.cnf` 添加: ```ini [mysqld] lower_case_table_names=0 # 0=区分大小写(Linux默认),1=不区分 ``` 重启 MySQL 服务生效: ```bash sudo systemctl restart mysql ``` - **文件权限问题**: 验证数据目录权限: ```bash ls -l /var/lib/mysql/liuyumeng | grep is_sb chown -R mysql:mysql /var/lib/mysql # 重置权限 ``` --- ### 总结流程图 ```mermaid graph TD A[出现错误 ERROR 1146] --> B{表是否存在?} B -->|否| C[创建表或检查自动建表配置] B -->|是| D{表名大小写是否正确?} D -->|否| E[使用反引号指定正确大小写] D -->|是| F{数据库上下文是否正确?} F -->|否| G[切换数据库或指定库名] F -->|是| H[检查表状态/刷新缓存] H --> I[验证系统配置] ``` > **关键点**: > - 大小写敏感是 Linux 系统最常见原因(90%案例)[^1][^4] > - 显式指定数据库反引号包裹表名可避免歧义 > - 框架自动建表需检查连接参数(如 `nullCatalogMeansCurrent=true`)[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值