1. 程式人生 > 其它 >多表聯查,navicat,pymysql

多表聯查,navicat,pymysql

目錄

多表聯查的兩種方式

學會連表操作之後也就課連線N多張表

思路:將拼接之後的表起別名當初一張表再去與其他表拼接 在起別名當作一張表 再去與其他表拼接 其次往復即可

  1. 連表操作

    • inner join 內連線

      select * from emp inner join dep on emp.dep_id = dep.id;
      # 只連線兩張表中的共有的資料部分
      
    • left join 左連線

      select * from emp left join dep on emp.dep_id = dep.id;
      # 以左表為基準 展示左表所有的資料 如果沒有對應項則用null填充
      
    • right join 右連線

      select * from emp right join dep on emp.dep_id = dep.id;
      # 以右表為基準,展示所有右表的資料如果沒有對應則用null填充
      
    • union 全連線

      select * from emp left join dep on emp.dep_id = dep.id
      union
      select * from emp right join dep on emp.dep_id = dep.id;
      # 以左右表為基準 展示所有的資料各自沒有的全部null填充
      
  2. 子查詢
    將一條SQL語句用括號括起來當初另外一條SQL語句的查詢條件

    # 題目:求姓名是jason的員工部門名稱
    #子查詢類似於我們日常生活中解決問題的方式:分佈操作
    #1.先根據jason獲取部門編號
    select dep_id from emp where name='jason';
    #2.再根據部門編號獲取部門名稱
    select name from dep where id =200;
    # 總結
    select name from dep where id =(select dep_id from emp where name='jason');
    '''
    很多時候多表查詢需要結合實際情況判斷用那種更所時候甚至是相互配合使用
    '''
    
  3. 很多時候多表查詢需要結合實際情況判斷用那種更所時候甚至是相互配合使用

小知識點

  1. concat 與 concat_ws

    • concat用於分組之前的欄位拼接操作

      select concat(name,'$',sex) from emp;
      
    • concat_ws也是分組之前拼接多個欄位並且中間的連線符一致

      select concat_ws('|',name,sex,age,dep_id) from emp;
      
  2. exists
    sql1 exists sql2
    sql2有結果的情況下才會執行sql1否則不執行sql1返回空資料

    select name from dep where exists (select dep_id from emp where name='jj');
    
    #常見exists
    drop table if exists e1;
    
  3. 表相關SQL補充

    • 修改表名

      alter table 表名 rename 新表名;
      
    • 新增欄位

      alter table 表名 add 欄位名 欄位型別(數字) 約束條件;
      # 約束條件可以不寫 預設新增最後一行
      alter table 表名 add 欄位名 欄位型別(數字) 約束條件 after 已有欄位;  # 新增欄位到指定欄位下面
      alter table 表名 add 欄位名 欄位型別(數字) 約束條件 first;# 新增欄位到第一行
      
    • 修改欄位

      alter table 表名 change 舊欄位名 新欄位名 欄位型別(數字) 約束條件;
       	alter table 表名 modify 欄位名 新欄位型別(數字) 約束條件;
      
    • 刪除欄位

      alter table 表名 drop 欄位名;  # 刪除欄位
      
    • 關於外來鍵的新增和刪除
      增加

      #1.再已經建立好的表後必須要先新增欄位,然後在新增外來鍵。
      alter table 表名 add 欄位 欄位型別(數字) 約束條件;
      #2.新增外來鍵
      alter table 表名 add constraint 外來鍵名稱 foreign key(本表字段) references 要關聯表(要關聯欄位);
      
      


      刪除

      #1.先刪除外來鍵
      alter table 表名 drop foreign key 外來鍵名;
      #key 名這個也要刪除
      alter table 表名 drop key 名;
      # 最後刪除這個外來鍵欄位
      alter table 表名 drop 欄位名
      

第三方開發的用來充當資料庫客戶端簡單快捷的操作介面

無論第三方軟體有多花裡胡哨 底層的本質還是sql

能操作資料庫的第三方視覺化軟體有很多 其中針對mysql最出名的就是navicat

  1. 瀏覽器搜尋navicat直接下載
    版本很多、能夠充當的資料庫客戶端也很多

  2. 本地化方式
    推薦無限使用,

  3. 常用操作
    有些功能可能需要自己修改SQL預覽
    建立庫 表 記錄 外來鍵
    逆向資料庫到模型 模型建立
    新建查詢可以編寫SQL語句並自帶提示功能

  4. SQL語句註釋語法

    --單行註釋
    # 單行註釋

    \**\ 多行註釋

    轉儲存SQL檔案,與匯入SQL檔案

多表查詢練習題

"""
編寫複雜的SQL不要想著一口氣寫完
	一定要先明確思路 然後一步步寫一步步查一步步補
"""
1、查詢所有的課程的名稱以及對應的任課老師姓名
4、查詢平均成績大於八十分的同學的姓名和平均成績
7、查詢沒有報李平老師課的學生姓名
8、查詢沒有同時選修物理課程和體育課程的學生姓名
9、查詢掛科超過兩門(包括兩門)的學生姓名和班級

-- 1、查詢所有的課程的名稱以及對應的任課老師姓名
# 1.先確定需要用到幾張表  課程表 分數表
# 2.預覽表中的資料 做到心中有數
-- select * from course;
-- select * from teacher;
# 3.確定多表查詢的思路 連表 子查詢 混合操作
-- SELECT
-- 	teacher.tname,
-- 	course.cname
-- FROM
-- 	course
-- INNER JOIN teacher ON course.teacher_id = teacher.tid;
-- 4、查詢平均成績大於八十分的同學的姓名和平均成績
# 1.先確定需要用到幾張表 學生表 分數表
# 2.預覽表中的資料
-- select * from student;
-- select * from score;
# 3.根據已知條件80分 選擇切入點 分數表
# 求每個學生的平均成績 按照student_id分組 然後avg求num即可
-- select student_id,avg(num) as avg_num from score group by student_id having avg_num>80;
# 4.確定最終的結果需要幾張表 需要兩張表 採用連表更加合適
-- SELECT
-- 	student.sname,
-- 	t1.avg_num
-- FROM
-- 	student
-- INNER JOIN (
-- 	SELECT
-- 		student_id,
-- 		avg(num) AS avg_num
-- 	FROM
-- 		score
-- 	GROUP BY
-- 		student_id
-- 	HAVING
-- 		avg_num > 80
-- ) AS t1 ON student.sid = t1.student_id;
-- 7、查詢沒有報李平老師課的學生姓名
# 1.先確定需要用到幾張表  老師表 課程表 分數表 學生表
# 2.預覽每張表的資料
# 3.確定思路 思路1:正向篩選 思路2:篩選所有報了李平老師課程的學生id 然後取反即可
# 步驟1 先獲取李平老師教授的課程id
-- select tid from teacher where tname = '李平老師';
-- select cid from course where teacher_id = (select tid from teacher where tname = '李平老師');
# 步驟2 根據課程id篩選出所有報了李平老師的學生id
-- select distinct student_id from score where course_id in (select cid from course where teacher_id = (select tid from teacher where tname = '李平老師'))
# 步驟3 根據學生id去學生表中取反獲取學生姓名
-- SELECT
-- 	sname
-- FROM
-- 	student
-- WHERE
-- 	sid NOT IN (
-- 		SELECT DISTINCT
-- 			student_id
-- 		FROM
-- 			score
-- 		WHERE
-- 			course_id IN (
-- 				SELECT
-- 					cid
-- 				FROM
-- 					course
-- 				WHERE
-- 					teacher_id = (
-- 						SELECT
-- 							tid
-- 						FROM
-- 							teacher
-- 						WHERE
-- 							tname = '李平老師'
-- 					)
-- 			)
-- 	)
-- 8、查詢沒有同時選修物理課程和體育課程的學生姓名(報了兩門或者一門不報的都不算)
# 1.先確定需要的表  學生表 分數表 課程表
# 2.預覽表資料
# 3.根據給出的條件確定起手的表
# 4.根據物理和體育篩選課程id
-- select cid from course where cname in ('物理','體育');
# 5.根據課程id篩選出所有跟物理 體育相關的學生id
-- select * from score where course_id in (select cid from course where cname in ('物理','體育'))
# 6.統計每個學生報了的課程數 篩選出等於1的
-- select student_id from score where course_id in (select cid from course where cname in ('物理','體育'))
-- group by student_id
-- having count(course_id) = 1;
# 7.子查詢獲取學生姓名即可
-- SELECT
-- 	sname
-- FROM
-- 	student
-- WHERE
-- 	sid IN (
-- 		SELECT
-- 			student_id
-- 		FROM
-- 			score
-- 		WHERE
-- 			course_id IN (
-- 				SELECT
-- 					cid
-- 				FROM
-- 					course
-- 				WHERE
-- 					cname IN ('物理', '體育')
-- 			)
-- 		GROUP BY
-- 			student_id
-- 		HAVING
-- 			count(course_id) = 1
-- 	) 
-- 9、查詢掛科超過兩門(包括兩門)的學生姓名和班級
# 1.先確定涉及到的表	分數表 學生表 班級表
# 2.預覽表資料
-- select * from class
# 3.根據條件確定以分數表作為起手條件
# 步驟1 先篩選掉大於60的資料
-- select * from score where num < 60;
# 步驟2 統計每個學生掛科的次數
-- select student_id,count(course_id) from score where num < 60 group by student_id;
# 步驟3 篩選次數大於等於2的資料
-- select student_id from score where num < 60 group by student_id having count(course_id) >= 2;
# 步驟4 連線班級表與學生表 然後基於學生id篩選即可
SELECT
	student.sname,
	class.caption
FROM
	student
INNER JOIN class ON student.class_id = class.cid
WHERE
	student.sid IN (
		SELECT
			student_id
		FROM
			score
		WHERE
			num < 60
		GROUP BY
			student_id
		HAVING
			count(course_id) >= 2
	);

pymysql操作MySQL

pymysql模組
	pip3 install pymysql
 
import pymysql

# 1.連線MySQL服務端
conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123',
    db='db4_03',
    charset='utf8mb4'
)
# 2.產生遊標物件
# cursor = conn.cursor()  # 括號內不填寫額外引數 資料是元組 指定性不強  [(),()]
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)  # [{},{}]
# 3.編寫SQL語句
# sql = 'select * from teacher;'
sql = 'select * from score;'
# 4.傳送SQL語句
affect_rows = cursor.execute(sql)  # execute也有返回值 接收的是SQL語句影響的行數
print(affect_rows)
# 5.獲取SQL語句執行之後的結果
res = cursor.fetchall()
print(res)

作業

  1. 查詢所有的課程的名稱以及對應的任課老師姓名

  2. 查詢學生表中男女生各有多少人

  3. 查詢物理成績等於100的學生的姓名

  4. 查詢平均成績大於八十分的同學的姓名和平均成績

  5. 查詢所有學生的學號,姓名,選課數,總成績

  6. 查詢姓李老師的個數

  7. 查詢沒有報李平老師課的學生姓名

  8. 查詢物理課程比生物課程高的學生的學號

    
    
  9. 查詢沒有同時選修物理課程和體育課程的學生姓名

  10. 查詢掛科超過兩門(包括兩門)的學生姓名和班級

  11. 查詢選修了所有課程的學生姓名

  12. 查詢李平老師教的課程的所有成績記錄

  13. 查詢全部學生都選修了的課程號和課程名

  14. 查詢每門課程被選修的次數

  15. 查詢之選修了一門課程的學生姓名和學號

  16. 查詢所有學生考出的成績並按從高到低排序(成績去重)

  17. 查詢平均成績大於85的學生姓名和平均成績

  18. 查詢生物成績不及格的學生姓名和對應生物分數

  19. 查詢在所有選修了李平老師課程的學生中,這些課程(李平老師的課程,不是所有課程)平均成績最高的學生姓名

  20. 查詢每門課程成績最好的前兩名學生姓名

  21. 查詢不同課程但成績相同的學號,課程號,成績

  22. 查詢沒學過“葉平”老師課程的學生姓名以及選修的課程名稱;

  23. 查詢所有選修了學號為1的同學選修過的一門或者多門課程的同學學號和姓名;

  24. 任課最多的老師中學生單科成績最高的學生姓名