1.完整語段的增刪改 2.單表查詢 3.多表查詢
阿新 • • 發佈:2019-01-14
''' 1.所有資料按順序插入 insert [into] 表名 values(值1, ..., 值n)[, ...,(值1, ..., 值n)]; 2.指定欄位匹配插入,可以任意順序 insert [into] 表名(欄位2, 欄位1, ..., 欄位n) values (值2, 值1, ..., 值n)[, ..., (值2, 值1, ..., 值n)]; 3.插入查詢結果 insert [into] 表1(欄位1, ..., 欄位n) select 欄位1, ..., 欄位n from 表2 [條件]; ''' # eg: 1 create table t1( id int auto_increment, x int, y int, primary key(id) ); insert t1 values (1, 2, 3), (2, 20, 30); # 按順序插入 insert into t1(y, x) values (300, 200); # 按規定欄位順序指定插入 實現新表對已有表的欄位、約束及資料的拷貝 create table nt1 like t1; # 複製表即完整結構 insert into nt1 select * from t1; # 複製所有資料 create table tt1( x int, z int ); insert into tt1 values (999, 888); insert into nt1(x) select x from tt1; # 將tt1中指定欄位插入到nt1中指定的欄位 insert into nt1(x, y) select x,z from tt1; # tt1x及z欄位的結果賦值給nt1中x,y欄位 #必須按照規定格式寫,如果用一下兩種方式 insert into nt1 select * from tt1; 報錯:Column count doesn't match value count at row 1 列計數與第1行中的值計數不匹配 insert into nt1(x,y) select(x,z) from tt1; 報錯:Operand should contain 1 column(s) 運算元應包含1列(s)
''' 1.會記錄自增資訊,操作會被日誌記錄,效率低 delete from 表名 [條件]; mysql> select * from t1; +----+------+------+ | id | x | y | +----+------+------+ | 1 | 2 | 3 | | 2 | 20 | 30 | | 3 | 200 | 300 | +----+------+------+ delete from t1; # 沒有條件的情況下是清空所有資料, 但會記錄自增資訊 insert into t1(x, y) values(6, 66); mysql> select * from t1; +----+------+------+ | id | x | y | +----+------+------+ | 4 | 6 | 66 | +----+------+------+ 2.清空表,會重置自增資訊 truncate table 表名; truncate table nt1; insert into nt1(x, y) values(6, 66); mysql> select * from nt1; +----+------+------+ | id | x | y | +----+------+------+ | 1 | 6 | 66 | +----+------+------+ '''
''' update 表名 set 欄位1=值1[, ..., 欄位n=值n] [條件] update tt1 set x=666; # 無條件, 全改 update tt1 set x=777, z=555 where z<888; # 只修改滿足條件的行 '''
''' select [distinct] 欄位1 [as 別名], ..., 欄位n [as 別名] from [庫名.]表名 [ where 約束條件 group by 分組依據 having 過濾條件 order by 排序的欄位 limit 限制顯示的條數 ]; 注: #distinct去重 1.查表中所有欄位用*表示 2.條件的書寫規則嚴格按照語法順序書寫,可以預設,但不可以錯序 3.約束條件的流程:from -> where -> group by -> having -> distinct -> order by -> limit 4.欄位可以起別名 5.欄位可以直接做運算 select age + 1 'new_age' from emp; 6.分組後的條件均可以使用聚合函式 ''' ''' 3. def from(): return "查詢的檔案" def where(file): return "條件篩選後的結果" def group_by(res): return "分組後的結果" def having(res): return "再次過濾後的結果" def distinct(res): return "去重後的結果" def order_by(res): return "排序後的結果" def limit(res): return "限制條數後的結果" def select(from=from, where=null, ..., limit=null): file = from() res = where(file) if where else file res = group_by(res) if group_by else res ... res = limit(res) if limit else res return res select(where=where, group_by=group_by) ''' #注意:約束條件的流程:from -> where -> group by -> having -> distinct -> order by -> limit
CREATE TABLE `emp` ( `id` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL, `gender` enum('男','女','未知') NULL DEFAULT '未知', `age` int(0) NULL DEFAULT 0, `salary` float NULL DEFAULT 0, `area` varchar(20) NULL DEFAULT '中國', `port` varchar(20) DEFAULT '未知', `dep` varchar(20), PRIMARY KEY (`id`) ); INSERT INTO `emp` VALUES (1, 'yangsir', '男', 42, 10.5, '上海', '浦東', '教職部'), (2, 'egon', '男', 38, 9.4, '山東', '濟南', '教學部'), (3, 'jerry', '女', 30, 3.0, '江蘇', '張家港', '教學部'), (4, 'tank', '女', 28, 2.4, '廣州', '廣東', '教學部'), (5, 'jiboy', '男', 28, 2.4, '江蘇', '蘇州', '教學部'), (6, 'zero', '男', 28, 8.8, '中國', '黃浦', '諮詢部'), (7, 'owen', '男', 28, 8.8, '安徽', '宣城', '教學部'), (8, 'ying', '女', 36, 1.2, '安徽', '蕪湖', '諮詢部'), (9, 'kevin', '男', 36, 5.8, '山東', '濟南', '教學部'), (10, 'monkey', '女', 28, 1.2, '山東', '青島', '教職部'), (11, 'san', '男', 30, 9.0, '上海', '浦東', '諮詢部'), (12, 'san1', '男', 30, 6.0, '上海', '浦東', '諮詢部'), (13, 'san2', '男', 30, 6.0, '上海', '浦西', '教學部');
concat(欄位1,...,欄位n):完成欄位的拼接 concat_ws(x, 欄位1,...,欄位n):完成欄位的拼接,x為連線符 lower():小寫 upper():大寫 ceil():向上取整 floor():向下取整 round():四捨五入
select concat(area, '-', port) as '家鄉' from emp; # 上海-浦東... 屬於起的別名家鄉列,as可有可無 select concat_ws("-", name, area, port) '資訊' from emp; # yangsir-上海-浦東... 屬於起的別名資訊列 以"-"字元拼接後面的所有欄位 select upper(name) 'name', gender, age from emp; # 可以指定多個欄位 select name, ceil(salary), floor(salary), round(salary) from emp where name='kevin'; # 數學函式 +-------+--------------+---------------+---------------+ | name | ceil(salary) | floor(salary) | round(salary) | +-------+--------------+---------------+---------------+ | kevin | 6 | 5 | 6 | +-------+--------------+---------------+---------------+ # 去重前提: 所查所有欄位的綜合結果完全相同, 才認為是重複的, 只保留重複中的一行資料 select distinct area from emp; select distinct area, port from emp;
''' 1.比較運算子 = | < | > | <= | >= | != select * from emp where area!="上海"; 2.區間運算子 between 10 and 20:10~20 in(10, 20, 30):10或20或30 select * from emp where id between 3 and 5; # [3, 5], 閉合區間,包含3和5,三行資料(3,4,5) select * from emp where id in(2, 4, 6, 8, 10, 12, 14, 16, 18); # 分離的區間,2,4,6,8,10,12都會被顯示 3.邏輯運算子 and | or | not select * from emp where area="山東" and port="濟南"; 4.相似運算子 like '_owen%':模糊匹配字串owen,_表示一個字元,%表示任意字元 # 匹配的欄位為en,想得到的結果為owen select * from emp where name like '__en%'; # 在en前可以出現2個任意字元, 之後可以出現0或多個任意字元,如果前面只有一個_那麼就沒有匹配結果 ''' # 需求: # 查詢姓名有數字的員工資訊
# 為什麼要使用正則匹配? like完成模糊匹配, 但功能侷限, 可以模糊個數, 但不能模糊型別, 正則可以完成型別及個數的模糊匹配 ''' 語法:欄位 regexp '正則表示式' 注:只支援部分正則語法 ''' # 完成需求: select * from emp where name regexp '.*[0-9]+.*';
''' 分組:根據欄位相同值形成不同的類別,不明確分組其實整個表就為一個預設大組,大組(整個表) 原因:把以值共性得到的類別作為考慮單位,不再關係單條記錄,而且一組記錄 結果:只能考慮組內多條資料的聚會結果(聚合函式結果),分組的欄位同樣是聚合結果,如:組內的最大最小值 將下面資訊加入配置檔案(my.ini) mysqld下面,然後重啟服務services.msc,這個就是分組安全模式: sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 聚合函式: max():最大值 min():最小值 avg():平均值 sum():和 count():記數 group_concat():組內欄位拼接,用來檢視組內其他欄位 ''' ''' 注意:from emp 後面是聚合結果,前面select後也要是聚合函式或結果 eg:1 每個部門的平均薪資 select dep, avg(salary) '平均薪資' from emp group by dep; eg:2 每個部門都有哪些人 select dep, group_concat(name) from emp group by dep; +-----------+---------------------------------------+ | dep | group_concat(name) | +-----------+---------------------------------------+ | 諮詢部 | san1,san,ying,zero | | 教學部 | san2,kevin,owen,jiboy,tank,jerry,engo | | 教職部 | monkey,yangsir | +-----------+---------------------------------------+ 需求: 各性別中附屬於教學部的最高薪資 select max(salary) '最高薪資', gender from emp where dep='教學部' group by gender; 思考: 想知道需求中員工的姓名 => 子查詢 上方結果: 男的最高薪資對應的人名, 女的最高薪資對應的人名 # select group_concat(name), max(salary) '最高薪資', gender from emp where dep='教學部' group by gender; 錯誤 ''' ''' 1. 14條資料部門有3個, 並且每個部分有多條記錄, 可以作為分組依據, 同理, 性別也可以 # select * from emp group by dep; select dep from emp group by dep; # 非分組安全模式下, 可以查詢非聚合結果, 顯示的是第一條記錄, 沒有意義, select name from emp group by dep; 會顯示結果 #分組安全模式下不能查詢非聚合結果的欄位 select name from emp group by dep; 直接報錯:'db2.emp.name' isn't in GROUP BY 2. 如果就像以姓名進行分組, 可以, 但沒多大意義, 原因name值基本上都不相同, 以組考慮會導致組內大多隻要一條記錄(自成一組), 組的利用就不是很強烈, 此類分組是無意義的 select name from emp group by name; # 可以分組, 但沒必要 '''
#想知道需求中員工的姓名 => 子查詢 # res = select max(salary) '最高薪資', gender from emp where dep='教學部' group by gender; # select name from emp where (salary 跟 res作比較) # 一個查詢依賴於另一個查詢的結果 => 一個查詢的結果作為另外一個查詢的條件 => 子查詢 #什麼是子查詢? #一個查詢的結果作為另一個查詢的條件.
''' 子查詢:將一條查詢結果作為另外一條查詢的條件 語法:一條select語句用()包裹得到的結果作為另一條select語句的條件 # 偽sql: select * from emp where salary =|in (select salary from emp where 條件) 單行子查詢: 子查詢語句的結果為一行資料,可以結合 = | < | > | <= | >= | != 運算子來完成父查詢 select salary from emp where salary > 10; # => 作為子查詢 這個只有一個數據,可以用單行子查詢 # 查詢姓名,性別.地區,基於薪資大於10的結果的查詢結果 eg: 1 select name, gender, area from emp where salary = (select salary from emp where salary > 10); 多行子查詢: 子查詢語句的結果為多行資料,可以結合 in | all | any 運算子來完成父查詢 in:任意單一值,一次只能考慮子查詢中的一個結果 all:全部值,將子查詢結果作為一個整體考慮 any:任意多個值:子查詢的每一個結果都可以作為參考依據 eg: 2 # 子查詢的結果 (9.4, 3) select * from emp where salary in (select max(salary) '最高薪資' from emp where dep='教學部' group by gender); # 遍歷14條資料, 14條資料的salary在(9.4, 3)區域中,就可以完成匹配, 結果為兩條(9.4和3那兩條) select * from emp where salary < all(select max(salary) '最高薪資' from emp where dep='教學部' group by gender); # 遍歷14條資料, salary要小於(9.4, 3)中的每一個, 反映就是小於3, 結果為薪資1.2和2.4的那四條資料 select * from emp where salary > any(select max(salary) '最高薪資' from emp where dep='教學部' group by gender); # 遍歷14條資料, salary大於9.4或大於3的資料均滿足條件, 結果就是刨除小於等於3的那幾條資料 '''
''' why:完成在分組之後的篩選 注意:having條件是實現聚合結果層面上的篩選 => 拿聚會結果完成判斷 需求: 1.各部門的平均薪資 select dep, avg(salary) '平均薪資' from emp group by dep; 2.平均薪資大於6w的部門(部門與部門的平均薪資) 解決: 以dep進行分組, 以avg(salary)作為判斷條件(篩選) select dep, avg(salary) '平均薪資' from emp group by dep having avg(salary) > 6; # 總結: having通過聚合函式結果完成篩選 select 後面查詢的欄位也要用聚合的結果 having判斷也要用聚合的結果進行判斷 select max(salary) from emp having max(salary) > 9.4; # 雖然沒有明確書寫group by, 但在having中使用了聚合函式,所以該查詢就將整個表當做一個預設大表來考慮,所以查詢的欄位只能為聚合函式的結果 '''
''' why:完成排序 注意:可以使用聚合函式,哪怕沒有明確group by 升序 | 降序:asc | desc 預設升序 eg:order by age desc => 按照年齡降序 select * from emp order by age desc; 需求: 將部門按照部門平均工資降序方式排序 select dep,avg(salary) from emp group by dep order by avg(salary) desc; '''
''' why:限制最終結果的資料行數 注意:limit只與數字結合使用 應用: limit 1:只能顯示一行資料 limit 6,5:從第6+1行開始顯示5條資料(索引從0開始) select * from emp limit 1; select * from emp limit 6,5; 需求: 獲得薪資最高的人的一條資訊 select * from emp order by salary desc limit 1;