1》查詢語句的基本語法mysql
語法:
SELECT 屬性列表
FROM 表名
[WHERE 條件表達式 1]
[GROUP BY 屬性名1 [HAVING 條件表達式2]]
[ORDER BY 屬性名2 [ASC | DESC]]
屬性列表表示須要查詢的字段名
表名錶示指的表名
WHERE 表示指定查詢的條件
GROUP BY 指定的字段進行分組
若是GROUP BY 子句後面帶着HAVING關鍵字,那麼只有知足條件2才能輸出。正則表達式
2》在單表上查詢數據:
v 列出表的全部字段
root@zytest 16:19>select order_num,order_date,cust_id from orders;
v 使用*查出單表全部字段
root@zytest 16:22>select * from orders;
v 查詢指定的字段
在orders表中有3個字段,order_num、order_date、cust_id,咱們查詢其中2個。
root@zytest 16:22>select order_num,order_date from orders;
v where查詢指定記錄
root@zytest 16:53>select * from orders where cust_id=10003;sql
*****比較
root@zytest 16:53>select * from orders where cust_id<=10003;小於或者等於
root@zytest 16:56>select * from orders where cust_id>=10003;大於或者等於
root@zytest 16:56>select * from orders where cust_id>10003;大於
root@zytest 16:56>select * from orders where cust_id<10003;小於
root@zytest 16:57>select * from orders where cust_id != 10003; 不等於
root@zytest 16:57>select * from orders where cust_id <> 10003;排除掉10003數據庫
指定範圍
root@zytest 16:57>select * from orders where cust_id between 10003 and 10004;
root@zytest 16:57>select * from orders where cust_id not between 10003 and 10004;
指定集合
root@zytest 16:57>select * from orders where cust_id in(10001,10004);
root@zytest 16:57>select * from orders where cust_id not in(10003,10004);
匹配字符
root@zytest 16:57>select * from orders where cust_id like ‘10001’;
root@zytest 16:57>select * from orders where cust_id not like ‘10001’;
是否爲空值
root@zytest 16:57>select * from vendors where vend_state is null;
root@zytest 16:57>select * from vendors where vend_state is not null;
多條件查詢
root@zytest 16:57>select * from orders where cust_id=10003 and order_num=20005;
root@zytest 16:57>select * from orders where cust_id=10003 or cust_id=10005;less
查詢結果不重複(distinct)字段名
語法:select distinct 字段名
select distinct cust_id from orders;
查詢結果進行排序
語法:order by 屬性名 [ASC|DESC]
select distinct cust_id from orders where cust_id>10003 order by cust_id desc;
查詢數據進行分組group by
語法:group by 屬性名 [having 條件表達式][with rollup]
having用來限制分組後的顯示,知足條件表達式的結果將被顯示
with rollup 關鍵字將會在全部記錄的最後加上一條記錄,該記錄是上面全部記錄的總和.
group關鍵字一般和group_concat()函數一塊兒使用.group_concat把每一個分組指定的字段值顯示出來.函數
group by 使用having條件約束過濾having 跟where做用同樣。可是having只能用於group by 。
select sex,count(sex),group_concat(name) from student group by sex having sex='女';
group by 多個字段進行分組
select sex,count(sex),group_concat(name) from student group by sex,user_id having sex='女';
group by 與with rollup一塊兒使用
root@zytest 10:02>select sex,count(sex) from student group by sex;
得出了分組出來的數量。若是想獲得分組出來的總和怎麼辦?
咱們後面再加上with rollup就能夠得出。
root@zytest 10:02>select sex,count(sex) from student group by sex with rollup;
對單個字段進行普通分組
root@zytest 06:56>select * from student group by address;
結合group_concat()進行指定每一個分組的值
root@zytest 08:48>select sex,group_concat(name) from student group by sex;3d
使用limint限制查詢結果的數量
root@zytest 10:07>select * from student where user_id >2 limit 2;code
3》使用集合函數查詢數據:regexp
集合函數包括:
count() 用來統計記錄的條數
sum() 用來計算字段的值和總數
avg() 用來計算字段的值的平均值
max() 用來查詢字段的最大值
min() 用來查詢字段的最小值
count()總計全部記錄的條目總數
root@zytest 10:24>select count(*) from student;
sum字段值得總和
root@zytest 10:25>select sum(user_id) from student;
avg 取平均值
root@zytest 10:25>select avg(user_id) from student;
max()取字段值得最大值
root@zytest 10:27>select max(user_id) from student;
min()取字段值得最小值
root@zytest 10:28>select min(user_id) from student;
server
4》多表鏈接查詢:
1>內鏈接
具備相贊成義的字段,才能夠進行內鏈接:
root@zytest 15:56>select cust_name,cust_address,order_date from customers,orders
where customers.cust_id=orders.cust_id;
2>外鏈接
外鏈接包括左查詢和右查詢
select屬性名列表
from 表名1 left | right join 表名2 on 表名1.屬性名=表名2.屬性名;
左鏈接查詢:
能夠查詢出表名1裏面全部的數據,而表名2只能查出匹配的記錄。
如下例子:表名1=vendors(主表)表名2=products(匹配表)
root@zytest 17:42>select vendors.vend_id,prod_name,prod_price from vendors left join products on
vendors.vend_id=products.vend_id;
右鏈接查詢
能夠查詢出表名2全部的記錄。而表名1只能查出匹配記錄。
如下例子:表名2=products(主表) 表名1=vendors(匹配表)
root@zytest 17:52>select products.vend_id,prod_name from vendors right join products on
vendors.vend_id=products.vend_id;
看不到1006?由於products裏面沒有1006,因此在vendors表中不匹配。這裏用用vendors ID去匹配products。有則匹配。
複合查詢:
在左鏈接或者右鏈接查詢出來以後如何進一步過濾?
root@zytest 18:18>select products.vend_id,prod_name,vend_name,vendors.vend_id from vendors right
join products on vendors.vend_id=products.vend_id where products.prod_name='Safe';
在後面直接加where就好了。
5》子查詢:
子查詢時將一個查詢語句內嵌到另個查詢語句當中。內層查詢的查詢結果,能夠爲外層查詢語句提供查詢條件;
1>帶IN關鍵字的子查詢
insert into student values('10005','aaaaa','','aaaaaa');
insert into student values('10006','aaaaa','','aaaaaa');
insert into student values('10003','aaaaa','','aaaaaa');
root@zytest 18:40>select * from orders where cust_id in (select user_id from student);
root@zytest 18:55>select * from orders where cust_id in (select user_id from student) and cust_id>'10003';進一步過濾
6》合併查詢:
有時候須要多個表進行合併數據。咱們使用union和union all,使用union時系統會將合併的結果去掉重複。而且顯示。可是union all偏偏相反,不會去掉 重複,會把全部的內容所有顯示出來;
root@zytest 19:06>select vend_id from vendors union select vend_id from products;
root@zytest 19:07>select vend_id from vendors union all select vend_id from products;
7》爲表和字段取別名:
爲表取別名:
select * from student aa where aa.user_id='1';
爲字段取別名:
select user_id as alvinzeng from student;
mysql> select * from yy1 aa where aa.user_id=1;
+---------+-----------+
| user_id | user_name |
+---------+-----------+
| 1 | zhangsan |
+---------+-----------+
1 row in set (0.00 sec)
8》使用正則查看:
在咱們的mysql當中,照樣可使用正則表達式來查詢結果;
正則咱們使用關鍵字「regexp」來鏈接正則
select * from vendors where vend_name regexp '^An';以An開頭的
select * from vendors where vend_city regexp 's$';以s結尾的
select * from vendors where vend_city regexp '.d';若是字符後面包含d
select * from vendors where vend_city regexp 'd.'; d後面包含的任意字符
select * from vendors where vend_city regexp '[London]';只要包含中括號裏面任意一個字符的都會被顯示出來
select * from vendors where vend_city regexp '[^Paris]';匹配除了Paris之外的全部字符,也就是說Paris將被過濾掉了。
select * from vendors where vend_state regexp 'MI|OH';匹配MI或者OH任意一個知足都會被顯示出來。
select * from vendors where vend_state regexp 'M*';匹配以包含M後面的任何字符。
select * from vendors where vend_name regexp 'll+';表明多個字符前面或者後面的任何字符
select * from vendors where vend_city regexp 'd{1}';查詢d出現過1次或者N次
select * from vendors where vend_city regexp 'd{1,3}';查詢d出現過1次,最多出現3次,
=====================Mysql存儲過程與存儲函數=================
1》建立存儲過程:
語法:
MySQL中,建立存儲過程的基本形式以下:
1>CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
create 是建立的的意思
procedure 是指的建立的類型是存儲過程。
sp_name參數是存儲過程的名稱;
proc_parameter表示存儲過程的參數列表;
characteristic參數指定存儲過程的特性;
routine_body參數是SQL代碼的內容,能夠用BEGIN…END來標誌SQL代碼的開始和結束。
proc_parameter中的每一個參數由3部分組成。這3部分分別是輸入輸出類型、參數名稱和參數類型。其形式以下:
[ IN | OUT | INOUT ] param_name type
其中,IN表示輸入參數;OUT表示輸出參數; INOUT表示既能夠是輸入,也能夠是輸出; param_name參數是存儲過程的參數名稱;type參數指 定存儲過程的參數類型,該類型能夠是MySQL數據庫的任意數據類型。
說明:MySQL中默認的語句結束符爲分號(;)。存儲過程當中的SQL語句須要分號來 結束。爲了不衝突,首先用"DELIMITER &&"將MySQL的結束符 設置爲&&。最後再用"DELIMITER ;"來將結束符恢復成分號。這與建立觸發器時是同樣的。
2>存儲過程和存儲函數的區別:
存儲過程和函數目的是爲了可重複地執行操做數據庫的SQL語句的集合,區別是寫法和調用上:
寫法上:存儲過程的參數列表能夠有輸入參數,輸出參數,能夠輸入輸出參數。函數的參數列表只有輸入參數,而且有return<返回值類型,無長度說 明>
在返回值上的區別:存儲過程的返回值,能夠有多個值,函數返回值,只有一個值;
舉例1:
需求1、存儲過程一(功能返回Mysql的版本號、用戶、所在數據庫、用戶鏈接數、)
Delimiter &&
create procedure alvin1(
out getversion varchar(30),
out userversion varchar(30),
out userdatabase varchar(30),
out userconnection int)
reads sql data
begin
select version() into getversion;
select user() into userversion;
select database() into userdatabase;
select connection_id() into userconnection;
end &&
delimiter ;
call alvin1(@a,@b,@c,@d);
select @a,@b,@c,@d;
需求2、統計student id的數據量總共是多少?
create procedure alvin2(
out zycount int)
reads sql data
begin
select count(*) into zycount from student;
end&&
delimiter ;
call alvin2(@a);
select @a;
2》變量的使用:
在整個存儲和函數中,能夠定義和使用變量,用戶可使用declare關鍵字來定義變量,而後能夠爲變量賦值,這些變量的做用範圍是begin…end程序 中。
1>定義變量
declare aa_id int default 10;
2>爲變量賦值
set aa_id=1001;
IN參數例子:
root@zytest 23:15>delimiter &&
root@zytest 23:16>create procedure alvin1( #建立一個名字爲alvin1存儲過程
-> in p_in int) #設置傳入的參數類型和變量
-> begin
-> select p_in; #查詢第一次傳進來的參數
-> set p_in=2; #:從新給p_in 賦值後。覆蓋掉傳進來的參數值
-> select p_in; #:在查詢一次賦值
->end&&
root@zytest 23:19>delimiter ;
root@zytest 23:19>set @p_in=1;#開始傳入參數賦值
root@zytest 23:19>call alvin1(@p_in);#調用存儲過程
+------+
| p_in |
+------+
| 1| #傳入的值爲1,
+------+
1 row in set (0.03 sec)
+------+
| p_in |
+------+
| 2 | #過程中的二次賦值
+------+
1 row in set (0.03 sec)
Query OK 0 rows affected (0.03 sec)
root@zytest 23:20>select @p_in; #查詢外邊傳參賦值的結果
+-------+
| @p_in |
+-------+
| 1 |
+-------+
OUT參數例子:
root@zytest 23:41>delimiter &&
root@zytest 23:41>create procedure name_info(建立一個名稱爲name_info的存儲過程
-> out p_out int) #定義輸出的變量和數據類型
-> begin
-> select p_out; #查看輸出參數
-> set p_out=2; #給參數賦值
-> select p_out; #查詢賦值結果
->end&&
Query OK, 0 rows affected (0.00 sec)
root@zytest 23:42>delimiter ;
root@zytest 23:42>set @p_out=1; #傳入一個參數。看看是否會在call調用的時候顯示出來?
Query OK, 0 rows affected (0.00 sec)
root@zytest 23:42>call name_info(@p_out);
+-------+
| p_out |
+-------+
| NULL | #傳入的參數爲空
+-------+
1 row in set (0.01 sec)
+-------+
| p_out |
+-------+
| 2 | #存儲函數裏面賦值的參數調用成功
+-------+
1 row in set (0.01 sec)
root@zytest 23:42>select @p_out;
+--------+
| @p_out |
+--------+
| 2 | #:只看到存儲函裏面賦值的。傳入的參數無效。
+--------+
1 row in set (0.00 sec)
INOUT參數列子:
root@zytest 00:03>delimiter &&
root@zytest 00:03>create procedure alvin_name( #建立一個名爲alvin_name的函數
-> inout p_inout int) #建立一個能夠傳入和傳出的p_inout的變量和數據類型
-> begin
-> select p_inout; #:查詢傳入的數據
-> set p_inout=2; #:給p_inout的賦值
-> select p_inout; #:在此查詢p_inout的值
->end&&
root@zytest 00:04>delimiter ;
root@zytest 00:04>set @p_inout=1; #:開始傳入參數
Query OK, 0 rows affected (0.00 sec)
root@zytest 00:04>call alvin_name(@p_inout); #:開始調用
+---------+
| p_inout |
+---------+
| 1 | #使用inout既能夠傳入能夠傳出
+---------+
1 row in set (0.00 sec)
+---------+
| p_inout |
+---------+
| 2 | #使用inout既能夠傳入能夠傳出
+---------+
1 row in set (0.00 sec)
root@zytest 00:04>select @p_inout; #查詢最後結果
+----------+
| @p_inout |
+----------+
| 2 | #:能夠傳出也能夠傳入,最終返回結果爲2,
+----------+
1 row in set (0.00 sec)
3》建立存儲函數:
語法:create function sp_name([func_parameter[,…….]])
Returns type
[characteristic…]routine_body。
其中,sp_name參數是存儲函數的名稱。
Func_parameter 表示存儲函數的參數列表。
Returns type 指定返回的參數類型。
characteristic參數指定存儲函數的特性。
routine_body參數是SQL代碼的內容。
能夠用BEGIN…END來標誌 SQL代碼開始和結束。
create function 函數名(參數1 數據類型[,參數2 數據類型,參數3 數據類型])returns 返回值類型
begin
任意系列的sql語句;
return 返回值;
end;
注:與儲存過程不一樣
一、參數只有輸入型
二、向調用方返回結果值
常見的錯誤:
This function has none of DETERMINISTIC, NO SQL解決辦法
建立存儲過程時
出錯信息:
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
其中在function裏面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。若是咱們開啓了 bin-log, 咱們就必須爲咱們的function指定一個參數。
解決方法:
SQL code
mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF |
+---------------------------------+-------+
mysql> set global log_bin_trust_function_creators=1;
mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+w
| Variable_name | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | ON |
+---------------------------------+-------+
這樣添加了參數之後,若是mysqld重啓,那個參數又會消失,所以記得在my.cnf配置文件中添加:
log_bin_trust_function_creators=1
舉列:根據輸入的vend_id查詢到每一個用戶的vend_name。
delimiter&&
create function alvin11( #建立一個函數名稱爲alvin11
bb_id int)#定義一個參數類型和它的數據類型
returns varchar(20)#定義下面vend_name的返回數據類型
begin # 開始
return (select vend_name from vendors#返回 SQL語句查詢的結果,
where vend_id=bb_id);
end && #結束
delimiter ;#跳出整體段落。
select alvin11(1001);#調用存儲函數-查詢結果
4》流程控制:
1>存儲過程if語句使用方法:
delimiter&&
create procedure zy_if(in aa int,out bb int)
begin
if aa>20 then
set bb=30;
elseif aa=20
then
set bb=20;
else
set bb=15;
end if;
end&&
delimiter ;
開始調用1 aa=20
call zy_if(20,@bb);
select @bb;
開始調用2 aa=25
call zy_if(25,@bb);
select @bb;
開始調用3 aa=15
call zy_if(15,@bb);
select @bb;
2>存儲過程case用法
delimiter&&
create procedure zy_case(in aa int,inout bb int)
begin
case
when aa=20 then set bb=20;
when aa>20 and aa<=50 then set bb=30;
when aa>51 then set bb=60;
else set bb=15;
end case;
end&&
delimiter ;
開始調用驗證1
call zy_case(20,@bb);
select @bb;
開始調用驗證2
call zy_case(21,@bb);
select @bb;
開始調用驗證3
call zy_case(52,@bb);
select @bb;
開始調用驗證4
call zy_case(10,@bb);
select @bb;
3>存儲過程 while 循環使用,插入1萬條數據
delimiter&&
create procedure zy_while()
begin
declare count int default 0;
while count < 10000 do
insert into zybb (user_id,name)values(count,'aa1');
set count = count + 1;
end while;
end&&
delimiter ;
call zy_while();調用存儲過程
5》調用存儲過程和函數:
1>調用方式call +存儲過程名稱+參數
如:call alvin_name(@p_inout);
2>查詢結果
select @p_inout
6》查看存儲過程和函數:
1>查詢存儲過程
show procedure status;
查詢某具體存儲過程詳細
show create procedure alvin1\G;
2>查詢存儲函數
show function status;
查詢某個具體存儲函數詳細
show create function alvin10\G;
7》刪除存儲過程和函數:
1>刪除存儲過程 drop procedure alvin1; 2>刪除存儲函數 drop function alvin1;