您好,登錄后才能下訂單哦!
小編給大家分享一下mysql中子查詢與連接表的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
列出訂購物品TNT2的所有客戶:
select cust_id from orders where order_num IN (SELECT order_num from orderitems where prod_id = 'TNT2' )
格式化SQL
包含子查詢的SELECT
語句難以閱讀和調(diào)試,特別是它們較為復(fù)雜時更是如此。如上所示把子查詢分解為多行并且適當(dāng)?shù)剡M行縮進,能極大地簡化子查詢的使用。
對于能嵌套的子查詢的數(shù)目沒有限制,不過在實際使用時由于性能的限制,不能嵌套太多的子查詢。
注:
列必須匹配 在
WHERE
子句中使用子查詢(如這里所示),應(yīng)該保證SELECT
語句具有與WHERE
子句中相同數(shù)目的列。通常,
子查詢將返回單個列并且與單個列匹配,但如果需要也可以使用多個列。
除了子查詢可以放在where
中,還可以放到select
中去。
假如需要顯示customers
表中每個客戶的訂單總數(shù)。
select cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) as orders from customers ORDER BY cust_name
mysql
的運行過程是先執(zhí)行了customers
中查出來了cust_name
,cust_state
,cust_id
,然后執(zhí)行5次子查詢,查出來了結(jié)果。
逐漸增加子查詢來建立查詢 用子查詢測試和調(diào)試查詢很有技巧性,特別是在這些語句的復(fù)雜性不斷增加的情況下更是如此。用子查詢建立(和測試)查詢的最可靠的方法是逐漸進行,這與MySQL處理它們的方法非常相同。首先,建立和測試最內(nèi)層的查詢。然后,用硬編碼數(shù)據(jù)建立和測試外層查詢,并且僅在確認它正常后才嵌入子查詢。這時,再次測試它。對于要增加的每個查詢,重復(fù)這些步驟。這樣做僅給構(gòu)造查詢增加了一點點時間,但節(jié)省了以后(找出查詢?yōu)槭裁床徽#┑拇罅繒r間,并且極大地提高了查詢一開始就正常工作的可能性
下面介紹一下聯(lián)結(jié):
SELECT vend_name,prod_name,prod_price FROM vendors,products WHERE vendors.vend_id=products.vend_id ORDER BY vend_name, prod_name
注:
完全限定列名 在引用的列可能出現(xiàn)二義性時,必須使用完全限定列名(用一個點分隔的表名和列名)。如果引用一個沒有用表名限制的具有二義性的列名,MySQL將返回錯誤。
這里使用where 語句進行聯(lián)接的作用:
利用WHERE子句建立聯(lián)結(jié)關(guān)系似乎有點奇怪,但實際上,有一個很充分的理由。請記住,在一條SELECT語句中聯(lián)結(jié)幾個表時,相應(yīng)的關(guān)系是在運行中構(gòu)造的。在數(shù)據(jù)庫表的定義中不存在能指示MySQL如何對表進行聯(lián)結(jié)的東西。你必須自己做這件事情。在聯(lián)結(jié)兩個表時,你實際上做的是將第一個表中的每一行與第二個表中的每一行配對。WHERE子句作為過濾條件,它只包含那些匹配給定條件(這里是聯(lián)結(jié)條件)的行。沒有WHERE子句,第一個表中的每個行將與第二個表中的每個行配對,而不管它們邏輯上是否可以配在一起。
注:
笛卡兒積(
cartesian product
) 由沒有聯(lián)結(jié)條件的表關(guān)系返回的結(jié)果為笛卡兒積。檢索出的行的數(shù)目將是第一個表中的行數(shù)乘以第二個表中的行數(shù)。目前為止所用的聯(lián)結(jié)稱為等值聯(lián)結(jié)(equijoin
),它基于兩個表之間的相等測試。這種聯(lián)結(jié)也稱為內(nèi)部聯(lián)結(jié)。其實,對于這種聯(lián)結(jié)可以使用稍微不同的語法來明確指定聯(lián)結(jié)的類型。
下面的SELECT語句返回與前面例子完全相同的數(shù)據(jù):
SELECT vend_name,prod_name,prod_price FROM vendors INNER JOIN products on vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name
使用哪種語法 ANSI SQL
規(guī)范首選INNER JOIN
語法。此外,盡管使用WHERE
子句定義聯(lián)結(jié)的確比較簡單,但是使用明確的
聯(lián)結(jié)語法能夠確保不會忘記聯(lián)結(jié)條件,有時候這樣做也能影響性能。
性能考慮 MySQL
在運行時關(guān)聯(lián)指定的每個表以處理聯(lián)結(jié)。這種處理可能是非常耗費資源的,因此應(yīng)該仔細,不要聯(lián)結(jié)
不必要的表。聯(lián)結(jié)的表越多,性能下降越厲害。
多做實驗 正如所見,為執(zhí)行任一給定的SQL操作,一般存在不止一種方法。很少有絕對正確或絕對錯誤的方法。性能可能
會受操作類型、表中數(shù)據(jù)量、是否存在索引或鍵以及其他一些條件的影響。因此,有必要對不同的選擇機制進行實驗,以找
出最適合具體情況的方法。我們同樣可以使用多張表的聯(lián)接,但是有一個問題,因為表名多個地方使用,故而表名很長,那么可以使用表的別名。
如:
下面介紹一下幾種特殊的連接。
假如你發(fā)現(xiàn)某物品(其ID
為DTNTR
)存在問題,因此想知道生產(chǎn)該物品的供應(yīng)商生產(chǎn)的其他物品是否也存在這些問題。此查詢要求首先找到生產(chǎn)ID
為DTNTR
的物品的供應(yīng)商,然后找出這個供應(yīng)商生產(chǎn)的其他物品。
下面是解決此問題的一種方法:
你可能使用子查詢,這樣做:
select prod_id,prod_name from products where vend_id = (SELECT vend_id from products WHERE prod_id ='DTNTR')
同樣可以使用自聯(lián)接。
select t1.prod_id,t2.prod_name from products t1, products t2 where t1.vend_id = t2.vend_id and t1.prod_id='DTNTR'
用自聯(lián)結(jié)而不用子查詢 自聯(lián)結(jié)通常作為外部語句用來替代從相同表中檢索數(shù)據(jù)時使用的子查詢語句。雖然最終的結(jié)果是
相同的,但有時候處理聯(lián)結(jié)遠比處理子查詢快得多。應(yīng)該試一下兩種方法,以確定哪一種的性能更好。
無論何時對表進行聯(lián)結(jié),應(yīng)該至少有一個列出現(xiàn)在不止一個表中(被聯(lián)結(jié)的列)。標(biāo)準的聯(lián)結(jié)(前一章中介紹的內(nèi)部聯(lián)結(jié))返回所有數(shù)據(jù),甚至相同的列多次出現(xiàn)。自然聯(lián)結(jié)排除多次出現(xiàn),使每個列只返回一次。
怎樣完成這項工作呢?答案是,系統(tǒng)不完成這項工作,由你自己完成它。自然聯(lián)結(jié)是這樣一種聯(lián)結(jié),其中你只能選擇那些唯一的列。這一般是通過對表使用通配符(SELECT *
)對所有其他表的列使用明確的子集來完成的。
許多聯(lián)結(jié)將一個表中的行與另一個表中的行相關(guān)聯(lián)。但有時候會需要包含沒有關(guān)聯(lián)行的那些行。例如,可能需要使用聯(lián)結(jié)來完成以下工作:
比如:對每個客戶下了多少訂單進行計數(shù),包括那些至今尚未下訂單的客戶;
SELECT customers.cust_id,order_num from customers LEFT OUTER JOIN orders on customers.cust_id = orders.cust_id
這條SELECT
語句使用了關(guān)鍵字OUTER JOIN
來指定聯(lián)結(jié)的類型(而不是在WHERE
子句中指定)。但是,與內(nèi)部聯(lián)結(jié)關(guān)聯(lián)兩個表中的行不同的是,外部聯(lián)結(jié)還包括沒有關(guān)聯(lián)行的行。在使用OUTER JOIN
語法時,必須使用RIGHT
或LEFT
關(guān)鍵字
指定包括其所有行的表(RIGHT
指出的是OUTER JOIN
右邊的表,而LEFT指出的是OUTER JOIN
左邊的表)。
使用帶聚集函數(shù)的聯(lián)結(jié):
要檢索所有客戶及每個客戶所下的訂單數(shù):
SELECT customers.cust_id, COUNT(order_num) as num from customers LEFT OUTER JOIN orders on customers.cust_id = orders.cust_id GROUP BY cust_id
注意點:
1.注意所使用的聯(lián)結(jié)類型。一般我們使用內(nèi)部聯(lián)結(jié),但使用外部聯(lián)結(jié)也是有效的。
2.保證使用正確的聯(lián)結(jié)條件,否則將返回不正確的數(shù)據(jù)。
3.應(yīng)該總是提供聯(lián)結(jié)條件,否則會得出笛卡兒積。
4.在一個聯(lián)結(jié)中可以包含多個表,甚至對于每個聯(lián)結(jié)可以采用不同的聯(lián)結(jié)類型。雖然這樣做是合法的,一般也很有用,但應(yīng)該在一起測試它們前,分別測試每個聯(lián)結(jié)。這將使故障排除更為簡單。
看完了這篇文章,相信你對“mysql中子查詢與連接表的示例分析”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。