您好,登錄后才能下訂單哦!
這篇文章主要講解了“mysql中關鍵詞exists怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“mysql中關鍵詞exists怎么使用”吧!
SELECT column1 FROM t1 WHERE [conditions] and EXISTS (SELECT * FROM t2 );
括號中的子查詢并不會返回具體的查詢到的數據,只是會返回true或者false,如果外層sql的字段在子查詢中存在則返回true,不存在則返回false
即使子查詢的查詢結果是null,只要是對應的字段是存在的,子查詢中則返回true,下面有具體的例子
執行過程
1、首先進行外層查詢,在表t1中查詢滿足條件的column1
2、接下來進行內層查詢,將滿足條件的column1帶入內層的表t2中進行查詢,
3、如果內層的表t2滿足查詢條件,則返回true,該條數據保留
4、如果內層的表t2不滿足查詢條件,則返回false,則刪除該條數據
5、最終將外層的所有滿足條件的數據進行返回
mysql版本: 8.0.28
數據庫表設計:
學生表: t_student
CREATE TABLE `t_student` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '學生姓名', `age` int NOT NULL COMMENT '年齡', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='學生表';
導入部分數據
INSERT INTO `t_student` (`id`, `name`, `age`) VALUES (1, '小張', 10), (2, 'chenille', 13), (3, '小王', 15), (4, '小米', 11), (5, 'dong', 13), (6, 'xi', 12), (7, 'chenille', 13), (8, '小王地方', 15), (9, '米來', 11), (10, 'dong', 13), (11, '呵呵', 12), (12, 'chenille', 13), (13, '小趙', 15), (14, '小米-0', 11), (15, 'bei', 13), (16, 'xi-xx', 12), (17, 'chenille', 13), (18, '小王-hehe', 15), (19, '小米-qian', 11), (20, 'dong', 13), (21, 'xi', 12), (22, 'chenille', 13), (23, '小王-1', 15), (24, '小米-2', 11), (25, 'dong-3', 13), (26, 'xi-0', 12), (27, 'chenille-4', 13), (28, '小王-4', 15), (29, '小米-7', 11), (30, 'dong-1', 13), (31, 'xi-5', 12), (32, '貔貅', 10), (33, '耄耋', 12), (34, '饕餮', 9), (35, '龍', 13), (36, '青牛', 12);
班級學生表:t_class_student
CREATE TABLE `t_class_student` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `student_id` int NOT NULL COMMENT '學生ID', `class_id` int NOT NULL COMMENT '班號', `class_name` varchar(100) DEFAULT '' COMMENT '班級名稱', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='班級學生表';
導入部分數據
INSERT INTO `t_class_student` (`id`, `student_id`, `class_id`, `class_name`) VALUES (1, 1, 1, '一年級1班'), (2, 2, 1, '一年級1班'), (3, 3, 1, '一年級1班'), (4, 4, 1, '一年級1班'), (5, 5, 1, '一年級1班'), (6, 6, 1, '一年級1班'), (7, 7, 1, '一年級1班'), (8, 8, 1, '一年級1班'), (9, 9, 1, '一年級1班'), (10, 10, 1, '一年級1班'), (11, 11, 2, '一年級2班'), (12, 12, 2, '一年級2班'), (13, 13, 2, '一年級2班'), (14, 14, 2, '一年級2班'), (15, 15, 2, '一年級2班'), (16, 16, 2, '一年級2班'), (17, 17, 2, '一年級2班'), (18, 18, 2, '一年級2班'), (19, 19, 2, '一年級2班'), (20, 20, 2, '一年級2班'), (21, 21, 3, '二年級2班'), (22, 22, 3, '二年級2班'), (23, 23, 3, '二年級2班'), (24, 24, 3, '二年級2班'), (25, 25, 3, '二年級2班'), (26, 26, 3, '二年級2班'), (27, 27, 3, '二年級2班'), (28, 28, 3, '二年級2班'), (29, 29, 3, '二年級2班'), (30, 30, 3, '二年級2班'), (31, 31, 4, '三年級1班'); (32, 32, 4, null);
已分配班級的學生名單
select * from t_student as s where exists (select student_id from t_class_student where student_id = s.id);
未分配班級的學生名單
select * from t_student as s where not exists (select student_id from t_class_student where student_id = s.id);
已分配 三年級1班 的學生名單
select * from t_student as s where exists (select student_id from t_class_student where student_id = s.id and class_id = 4);
已分配 并且班級是 一年級1班 和 一年級2班 的學生名單
select * from t_student as s where exists (select student_id from t_class_student where student_id = s.id and class_id in (1, 2) );
查詢到的字段為null,但是子查詢返回的結果為true
select * from t_student as s where exists (select class_name from t_class_student where student_id = s.id and class_id = 4);
查詢全部學生名單
select * from t_student as s where exists (select student_id from t_class_student where 1=1);
已分配 三年級1班 的并且年齡大于10歲的學生名單
select * from t_student as s where age > 10 and exists (select student_id from t_class_student where student_id = s.id and class_id = 4);
上面的這些查詢其實也可以通過 in 關鍵字來實現,下面我們寫一下 in 關鍵字對應的查詢語句,
通過 in 實現已分配班級的學生名單 ????
select * from t_student as s where id in (select student_id from t_class_student where student_id = s.id);
通過 in 實現未分配班級的學生名單 ????
select * from t_student as s where id not in (select student_id from t_class_student where student_id = s.id);
下面我們來分析一下這兩個關鍵字使用效率到底那個更高呢?
循環由外向內,外層循環執行一次,內層循環則需要完整的執行一次,內層執行執行完后返回執行結果,外層循環繼續執行,直到外層循環完全執行完成
有了上面的執行原理的說明,我們明白了一個道理:內層循環次數的多少不會影響到外層的次數,但是外層循環的次數直接會影響到內層循環的次數,外層循環每多一次,內層循環就需要多完整的一次循環,所以我們優化的目標其實就是使外層的循環次數盡量少,總結來說:小表驅動大表。小表就是外層循環,大表就是內層循環,也就是盡量減少外層循環的次數
exists : 外表先進行循環查詢,將查詢結果放入exists的子查詢中進行條件驗證,確定外層查詢數據是否保留
in : 先查詢內表,將內表的查詢結果當做條件提供給外表查詢語句進行比較
通過上面的優化策略分析和exists和in的查詢原理的分析,將這兩塊內容結合起來其實就得出了我們想要的一個結論:
外層小表,內層大表(或者將sql從左到由來看:左面小表,右邊大表): exists 比 in 的效率高
外層大表,內層小表(或者將sql從左到由來看:左面大表,右邊小表): in 比 exists 的效率高
感謝各位的閱讀,以上就是“mysql中關鍵詞exists怎么使用”的內容了,經過本文的學習后,相信大家對mysql中關鍵詞exists怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。