一、完整版SQL語句的查詢
select
distinct post,avg(salary)
from
table
where
id > 1
group by
post`
having
avg(salary)>100
order by
avg(salary)
limit 5,5
group by:分組之后,分組依據是最小可識別單位,不能再直接獲取到其他字段信息,如果想要獲取其他字段信息,只能用額外的方法間接獲取,上述情況需要你設置嚴格模式,如果整個SQL語句沒有group by默認整體就是一組。
二、聚合函數
- max
- min
- avg
- sum
- count
ps:聚合函數只能在分組之后使用
三、distinct和limit
distinct(去重)去重一定要滿足數據是一模一樣的情況下,才能達到去重的效果,如果你查詢出來的數據中包含主鍵字段,那么不可能去重成功。
limit 5;只寫一個參數,從第一條開始展示5條
limit 5,5;從第五條開始,不包含第五條,展示五條
ps:MySQL對大小寫不敏感
四、模糊匹配和正則表達式匹配
1、模糊匹配
-
%:多個任意字符
-
_:單個任意字符
2、正則表達式
where name regexp "^j.*(n|y)$"
表示以j開頭,n或y結尾,中間是任意字符
.表示匹配除換行符之外的任意字符
*表示o到無窮
+表示1到無窮
?表示0或1
^表示以什么開頭
$表示以什么結尾
回顧re模塊
findall:分組優先,會將括號內正則匹配到的優先返回
match:從頭開始匹配,匹配到一個就返回
search:整體匹配,匹配到一個就返回
res=match('^j.*(n|y)$','jason')
print(res.group())
五、concat和concat_ws
concat和concat_ws在分組之前用
-
concat(name,':',age,':',salary) 用於拼接字符串
-
concat_ws(':',name,age,salary) 與上面的效果一致
與字符串的join方法類似,但有區別:join方法只能用在字符串之間。
':'.join(['1',2,'3']) 由於2是數字,會報錯
六、exists
exists關鍵字表示存在,在使用exists關鍵字使,內層查詢語句不返回查詢的記錄,而是返回一個真假值,True或False。
當返回True時,外層查詢語句將進行查詢
當返回False時,外層查詢語句不進行查詢
select * from emp where exists (select id from dep where id>203);
七、pymysql模塊
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
passwoord='123',
database='day38',
charset='utf8' # 不能加—
)
cursor=conn.cursor(pymysql.cursors.DictCursor) # 產生一個游標對象,以字典的形式返回查詢結果
sql = 'select * from teacher'
res = cursor.execute(sql) # 執行傳入的sql語句
print(res) # res是執行語句返回的數據條數
print(cursor.fetchone()) # 只獲取一條數據
print(cursor.fetchone()) # 只獲取一條數據
print(cursor.fetchone()) # 只獲取一條數據
cursor.scroll(2,'absolute') # 控制光標移動 absolute相對於起始位置,往后移動幾位
cursor.scroll(1,'relative') # relative相對於當前位置,往后移動幾位
print(cursor.fetchall()) # 獲取所有的數據,返回的結果是一個列表
cursor.close()
conn.close()
八、sql注入問題
import pymysql
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '123',
database = 'day38',
charset = 'utf8', # 編碼千萬不要加- 如果寫成了utf-8會直接報錯
autocommit = True # 這個參數配置完成后 增刪改操作都不需要在手動加conn.commit了
)
cursor = conn.cursor(pymysql.cursors.DictCursor) # 產生一個游標對象 以字典的形式返回查詢出來的數據 鍵是表的字段 值是表的字段對應的信息
# sql = 'insert into user(name,password) values("jerry","666")'
# sql = 'update user set name = "jasonhs" where id = 1'
sql = 'delete from user where id = 6'
cursor.execute(sql)
"""
增刪改操作 都必須加一句
conn.commit()操作
"""
# conn.commit()
# username = input('username>>>:')
# password = input('password>>>:')
# sql = "select * from user where name =%s and password = %s"
# print(sql)
# res = cursor.execute(sql,(username,password)) # 能夠幫你自動過濾特殊符號 避免sql注入的問題
# # execute 能夠自動識別sql語句中的%s 幫你做替換
# if res:
# print(cursor.fetchall())
# else:
# print('用戶名或密碼錯誤')
"""
sql注入 就是利用注釋等具有特殊意義的符號 來完成一些騷操作
后續寫sql語句 不要手動拼接關鍵性的數據
而是讓excute幫你去做拼接
"""
# 不要手動去拼接查詢的sql語句
username = input(">>>:").strip()
password = input(">>>:").strip()
sql = "select * from user where username='%s' and password='%s'"%(username,password)
# 用戶名正確
username >>>: jason' -- jjsakfjjdkjjkjs
# 用戶名密碼都不對的情況
username >>>: xxx' or 1=1 --asdjkdklqwjdjkjasdljad
password >>>: ''
九、增刪改
# 增
sql = "insert into user(username,password) values(%s,%s)"
rows = cursor.excute(sql,('jason','123'))
# 修改
sql = "update user set username='jasonDSB' where id=1"
rows = cursor.excute(sql)
"""
增和改單單執行excute並不會真正影響到數據,需要再執行conn.commit()才可以完成真正的增改
"""
# 一次插入多行記錄
res = cursor,excutemany(sql,[(),(),()]