數據查詢與存儲過程

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;

相關文章
相關標籤/搜索