1. 程式人生 > >MySQL筆記2——查詢專題

MySQL筆記2——查詢專題

子查詢(Subquery):

  • 指出現在其他SQL語句內的SELECT子句。
  • 子查詢巢狀在查詢內部,且必須始終出現在原括號內
  • 子查詢可以包含多個關鍵字或條件(如DISTINCT,GROUP BY,OREDR BY,LIMIT,函式等)
  • 子查詢外層查詢可以是SELECT,INSERT,UPDATE,SET或DO
  • 子查詢的返回結果可以是標量、某行、某列甚至是其子查詢

使用比較運算子的子查詢

語法:operand comparison_operator subquery

//查詢商品表中的平均價格
SELECT AVG(goods_price) FROM tdb_goods;

//對於平均值得到的結果進行四捨五入
SELECT ROUND(AVG(goods_price),2) FROM tdb_goods;

//將上邊的兩條語句合併:
SELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price>=(SELECT ROUND(AVG(goods_price),2) FROM tdb_goods);

當然,如果子查詢返回多個結果的時候可以用ANY,SOME或ALL修飾比較運算子

語法:
operand comparison_operator ANY(subquery)
operand comparison_operator SOME(subquery)
operand comparison_operator ALL(subquery)

原則:

. ANY SOME ALL
>,>= 最小值 最小值 最大值
<,<= 最大值 最大值 最小值
= 任意值 任意值
<>,!= 任意值
SELEC goods_id,goods_price,goods_name FROM tdb_goods WHERE goods_price>ANY(SELECT goods_price FROM tdb_goods WHERE goods_cate = '超極本');

使用[NOT] IN/EXISTS引發的子查詢

語法:
operand comparisson_operator [NOT] IN (subquery)

//=ANY運算子與IN等效。
//!=ALL或<>ALL運算子與NOT IN等效

有什麼用處

之前我們講過,INSERT…SELECT語句可以進行語句插入,其特殊之處在於:可以巢狀子查詢。

INSERT [INTO] tbl_name [(col_name,...)]
SELECT...   

eg:
INSERT tdb_goods_cates(cate_name) SELECT goods_cates FROM tdb_goods GROUP BY goods_cate; 

但是我們又需要引入一個全新的概念:

多表更新

語法:
table_reference
{[INNER |CROSS] JOIN |{LEFT |RIGHT} [OUTER] JOIN}
table_reference
ON conditional_expr

eg:
UPDATE tdb_goods INNER JOIN tdb_goods_cates ON goods cates
SET goods_cate = cate_id;

用來參照另外的表更新本表的記錄

例子中的樣例並不完整,之前還有兩步:
1.建立一個索引表
2.通過INSERT SELECT將資訊寫入新表
3.多表更新
此操作旨在將原表中大量重複的資料利用新表中的標號代替,以此達到減少儲存空間的目的

連線

table_reference
{[INNER |CROSS] JOIN |{LEFT |RIGHT} [OUTER] JOIN}   //內連線,左外連線,右外連線
table_reference
ONconditional_expr

資料表參照

table_reference
tbl_name [[AS] alias] | table_subquery [AS] alias

資料表可以使用tbl_name AS alias_name或tbl_name alias_name賦予別名

tbl_subquery可以作為子查詢使用在FRON子句中,這樣的子查詢必須為其賦予別名

INNER JOIN:僅顯示符合連線條件的記錄

  • mysql中,JOIN,CROSS JOIN和INNER JOIN是等價的
  • 通常使用ON設定連線條件,使用WHERE進行結果集記錄的過濾

內連線

SELECT goods_id,goods_name,cate_name FROM tdb_goods INNER JOIN tdb_goods_cates ON tdb_goods.cate_id = tdb_goods_cates.cate_id;
//查詢tdb_goods表和tdb_goods_cates表的內連線中商品id,商品名及品牌名

[OUTER] LEFT JOIN:左外連線

左外連線
顧名思義,結果為左表的全部且符合右表條件的。若坐左表中的某些元組不符合右表條件則對應元組的相應屬性顯示為NULL

[OUTER] RIGHT JOIN:右外連線

右外連線

多表連線

eg:

SELECT goods_id,goods_name,cate_name,brand_name,goods_price FROM tdb_goods AS g
INNER JOIN tdb_goods_cates AS c ON g.cate_id = c.cate_id
INNER JOIN tdb_goods_brands AS b ON g.brand_id = b.brand_id\G; 

無限級分類表設計

eg:

CREATE TABLE tdb_goods_typos(
    type_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    type_name VARCHAR(20) NOT NULL,
    parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0
);

自定義函式

CREATE FUNCTION function_name
RETURNS
{STRING |INTEGER |REAL |DECIMAL}
routine_body

函式體:

  • 函式體由合法的SQL語句構成
  • 函式體可以實簡單的SELECT或INSERT語句
  • 函式體如果未複合結構則使用BEGIN…END語句
  • 複合結構可以包含宣告,迴圈,控制結構

eg:

CREATE FUNCTION F1() RETURNS VARCHAR(30)

RETURN DATE_FORMAT(NOW(), '%Y年%m月%d日 %H點:%i分:%s秒');

若為複合結構則必須要包含在BEGIN…END之中

刪除自定義函式

DROP FUNCTION [IF EXISTS] function_name