多表查詢與pymysql


        
一、子查詢

#1:子查詢是將一個查詢語句嵌套在另一個查詢語句中。
#2:內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。
#3:子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
#4:還可以包含比較運算符:= 、 !=、> 、<等
1 帶IN關鍵字的子查詢


#查詢平均年齡在25歲以上的部門名
select id,name from department
where id in
(select dep_id from employee group by dep_id having avg(age) > 25);

#查看技術部員工姓名
select name from employee
where dep_id in
(select id from department where name='技術');

#查看不足1人的部門名(子查詢得到的是有人的部門id)
select name from department where id not in (select distinct dep_id from employee);

2 帶比較運算符的子查詢

#比較運算符:=、!=、>、>=、<、<=、<>
#查詢大於所有人平均年齡的員工名與年齡
mysql> select name,age from emp where age > (select avg(age) from emp);
+---------+------+
| name | age |
+---------+------+
| alex | 48 |
| wupeiqi | 38 |
+---------+------+
2 rows in set (0.00 sec)


#查詢大於部門內平均年齡的員工名、年齡
select t1.name,t1.age from emp t1
inner join
(select dep_id,avg(age) avg_age from emp group by dep_id) t2
on t1.dep_id = t2.dep_id
where t1.age > t2.avg_age;

3 帶EXISTS關鍵字的子查詢

EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。
而是返回一個真假值。True或False
當返回True時,外層查詢語句將進行查詢;當返回值為False時,外層查詢語句不進行查詢

#department表中存在dept_id=203,Ture
mysql> select * from employee
-> where exists
-> (select id from department where id=200);
+----+------------+--------+------+--------+
| id | name | sex | age | dep_id |
+----+------------+--------+------+--------+
| 1 | egon | male | 18 | 200 |
| 2 | alex | female | 48 | 201 |
| 3 | wupeiqi | male | 38 | 201 |
| 4 | yuanhao | female | 28 | 202 |
| 5 | liwenzhou | male | 18 | 200 |
| 6 | jingliyang | female | 18 | 204 |
+----+------------+--------+------+--------+

#department表中存在dept_id=205,False
mysql> select * from employee
-> where exists
-> (select id from department where id=204);
Empty set (0.00 sec)

二、pymysql模塊

1.鏈接、執行sql、關閉(游標)
import pymysql
user=input('用戶名: ').strip()
pwd=input('密碼: ').strip()


conn=pymysql.connect(host='localhost',user='root',password='123',database='egon',charset='utf8')
cursor=conn.cursor() #執行完畢返回的結果集默認以元組顯示
#cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)


#執行sql語句
sql='select * from userinfo where name="%s" and password="%s"' %(user,pwd) #注意%s需要加引號
print(sql)
res=cursor.execute(sql) #執行sql語句,返回sql查詢成功的記錄數目
print(res)

cursor.close()
conn.close()

if res:
print('登錄成功')
else:
print('登錄失敗')

2.execute()之sql注入

注意:符號--會注釋掉它之后的sql,正確的語法:--后至少有一個任意字符
根本原理:就根據程序的字符串拼接name='%s',我們輸入一個xxx' -- haha,用我們輸入的xxx加'在程序中拼接成一個判斷條件name='xxx' -- haha'
最后那一個空格,在一條sql語句中如果遇到select * from t1 where id > 3 -- and name='egon';則--之后的條件被注釋掉了

#1、sql注入之:用戶存在,繞過密碼
egon' -- 任意字符

#2、sql注入之:用戶不存在,繞過用戶與密碼
xxx' or 1=1 -- 任意字符

解決方法:

# 原來是我們對sql進行字符串拼接
# sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
# print(sql)
# res=cursor.execute(sql)

#改寫為(execute幫我們做字符串拼接,我們無需且一定不能再為%s加引號了)
sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引號,因為pymysql會自動為我們加上
res=cursor.execute(sql,[user,pwd]) #pymysql模塊自動幫我們解決sql注入的問題,只要我們按照pymysql的規矩來。

3.增、刪、改:conn.commit()

import pymysql
conn=pymysql.connect(host='localhost',user='root',password='123',database='egon')
cursor=conn.cursor()

#執行sql語句
#part1
# sql='insert into userinfo(name,password) values("root","123456");'
# res=cursor.execute(sql) #執行sql語句,返回sql影響成功的行數
# print(res)

#part2
# sql='insert into userinfo(name,password) values(%s,%s);'
# res=cursor.execute(sql,("root","123456")) #執行sql語句,返回sql影響成功的行數
# print(res)

#part3
sql='insert into userinfo(name,password) values(%s,%s);'
res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")]) #執行sql語句,返回sql影響成功的行數
print(res)

conn.commit() #提交后才發現表中插入記錄成功
cursor.close()
conn.close()

4.獲取插入的最后一條數據的自增ID

import pymysql
conn=pymysql.connect(host='localhost',user='root',password='123',database='egon')
cursor=conn.cursor()

sql='insert into userinfo(name,password) values("xxx","123");'
rows=cursor.execute(sql)
print(cursor.lastrowid) #在插入語句后查看

conn.commit()

cursor.close()
conn.close()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM