人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

mysql 子查詢與連接表詳情

發(fā)布日期:2022-02-05 18:38 | 文章來(lái)源:源碼之家

1、什么是子查詢?

列出訂購(gòu)物品TNT2的所有客戶:

select cust_id
from orders
where order_num IN (SELECT order_num
from orderitems
where prod_id = 'TNT2'
)

格式化SQL 包含子查詢的SELECT語(yǔ)句難以閱讀和調(diào)試,特別是它們較為復(fù)雜時(shí)更是如此。如上所示把子查詢分解為多行并且適當(dāng)?shù)剡M(jìn)行縮進(jìn),能極大地簡(jiǎn)化子查詢的使用。

對(duì)于能嵌套的子查詢的數(shù)目沒有限制,不過(guò)在實(shí)際使用時(shí)由于性能的限制,不能嵌套太多的子查詢。

注:

列必須匹配 在WHERE子句中使用子查詢(如這里所示),應(yīng)該保證SELECT語(yǔ)句具有與WHERE子句中相同數(shù)目的列。通常,
子查詢將返回單個(gè)列并且與單個(gè)列匹配,但如果需要也可以使用多個(gè)列。

除了子查詢可以放在where 中,還可以放到select中去。

假如需要顯示customers表中每個(gè)客戶的訂單總數(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 的運(yùn)行過(guò)程是先執(zhí)行了customers 中查出來(lái)了cust_namecust_state,cust_id,然后執(zhí)行5次子查詢,查出來(lái)了結(jié)果。

逐漸增加子查詢來(lái)建立查詢 用子查詢測(cè)試和調(diào)試查詢很有技巧性,特別是在這些語(yǔ)句的復(fù)雜性不斷增加的情況下更是如此。用子查詢建立(和測(cè)試)查詢的最可靠的方法是逐漸進(jìn)行,這與MySQL處理它們的方法非常相同。首先,建立和測(cè)試最內(nèi)層的查詢。然后,用硬編碼數(shù)據(jù)建立和測(cè)試外層查詢,并且僅在確認(rèn)它正常后才嵌入子查詢。這時(shí),再次測(cè)試它。對(duì)于要增加的每個(gè)查詢,重復(fù)這些步驟。這樣做僅給構(gòu)造查詢?cè)黾恿艘稽c(diǎn)點(diǎn)時(shí)間,但節(jié)省了以后(找出查詢?yōu)槭裁床徽#┑拇罅繒r(shí)間,并且極大地提高了查詢一開始就正常工作的可能性

下面介紹一下聯(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)二義性時(shí),必須使用完全限定列名(用一個(gè)點(diǎn)分隔的表名和列名)。如果引用一個(gè)沒有用表名限制的具有二義性的列名,MySQL將返回錯(cuò)誤。

這里使用where 語(yǔ)句進(jìn)行聯(lián)接的作用:

利用WHERE子句建立聯(lián)結(jié)關(guān)系似乎有點(diǎn)奇怪,但實(shí)際上,有一個(gè)很充分的理由。請(qǐng)記住,在一條SELECT語(yǔ)句中聯(lián)結(jié)幾個(gè)表時(shí),相應(yīng)的關(guān)系是在運(yùn)行中構(gòu)造的。在數(shù)據(jù)庫(kù)表的定義中不存在能指示MySQL如何對(duì)表進(jìn)行聯(lián)結(jié)的東西。你必須自己做這件事情。在聯(lián)結(jié)兩個(gè)表時(shí),你實(shí)際上做的是將第一個(gè)表中的每一行與第二個(gè)表中的每一行配對(duì)。WHERE子句作為過(guò)濾條件,它只包含那些匹配給定條件(這里是聯(lián)結(jié)條件)的行。沒有WHERE子句,第一個(gè)表中的每個(gè)行將與第二個(gè)表中的每個(gè)行配對(duì),而不管它們邏輯上是否可以配在一起。

注:

笛卡兒積(cartesian product) 由沒有聯(lián)結(jié)條件的表關(guān)系返回的結(jié)果為笛卡兒積。檢索出的行的數(shù)目將是第一個(gè)表中的行數(shù)乘以第二個(gè)表中的行數(shù)。目前為止所用的聯(lián)結(jié)稱為等值聯(lián)結(jié)(equijoin),它基于兩個(gè)表之間的相等測(cè)試。這種聯(lián)結(jié)也稱為內(nèi)部聯(lián)結(jié)。其實(shí),對(duì)于這種聯(lián)結(jié)可以使用稍微不同的語(yǔ)法來(lái)明確指定聯(lián)結(jié)的類型。

下面的SELECT語(yǔ)句返回與前面例子完全相同的數(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

使用哪種語(yǔ)法 ANSI SQL規(guī)范首選INNER JOIN語(yǔ)法。此外,盡管使用WHERE子句定義聯(lián)結(jié)的確比較簡(jiǎn)單,但是使用明確的
聯(lián)結(jié)語(yǔ)法能夠確保不會(huì)忘記聯(lián)結(jié)條件,有時(shí)候這樣做也能影響性能。

性能考慮 MySQL在運(yùn)行時(shí)關(guān)聯(lián)指定的每個(gè)表以處理聯(lián)結(jié)。這種處理可能是非常耗費(fèi)資源的,因此應(yīng)該仔細(xì),不要聯(lián)結(jié)
不必要的表。聯(lián)結(jié)的表越多,性能下降越厲害。

多做實(shí)驗(yàn) 正如所見,為執(zhí)行任一給定的SQL操作,一般存在不止一種方法。很少有絕對(duì)正確或絕對(duì)錯(cuò)誤的方法。性能可能
會(huì)受操作類型、表中數(shù)據(jù)量、是否存在索引或鍵以及其他一些條件的影響。因此,有必要對(duì)不同的選擇機(jī)制進(jìn)行實(shí)驗(yàn),以找
出最適合具體情況的方法。我們同樣可以使用多張表的聯(lián)接,但是有一個(gè)問題,因?yàn)楸砻鄠€(gè)地方使用,故而表名很長(zhǎng),那么可以使用表的別名。

如:

下面介紹一下幾種特殊的連接。

2、自聯(lián)接

假如你發(fā)現(xiàn)某物品(其IDDTNTR)存在問題,因此想知道生產(chǎn)該物品的供應(yīng)商生產(chǎn)的其他物品是否也存在這些問題。此查詢要求首先找到生產(chǎn)IDDTNTR的物品的供應(yīng)商,然后找出這個(gè)供應(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é)通常作為外部語(yǔ)句用來(lái)替代從相同表中檢索數(shù)據(jù)時(shí)使用的子查詢語(yǔ)句。雖然最終的結(jié)果是
相同的,但有時(shí)候處理聯(lián)結(jié)遠(yuǎn)比處理子查詢快得多。應(yīng)該試一下兩種方法,以確定哪一種的性能更好。

3、自然聯(lián)接

無(wú)論何時(shí)對(duì)表進(jìn)行聯(lián)結(jié),應(yīng)該至少有一個(gè)列出現(xiàn)在不止一個(gè)表中(被聯(lián)結(jié)的列)。標(biāo)準(zhǔn)的聯(lián)結(jié)(前一章中介紹的內(nèi)部聯(lián)結(jié))返回所有數(shù)據(jù),甚至相同的列多次出現(xiàn)。自然聯(lián)結(jié)排除多次出現(xiàn),使每個(gè)列只返回一次。

怎樣完成這項(xiàng)工作呢?答案是,系統(tǒng)不完成這項(xiàng)工作,由你自己完成它。自然聯(lián)結(jié)是這樣一種聯(lián)結(jié),其中你只能選擇那些唯一的列。這一般是通過(guò)對(duì)表使用通配符(SELECT * )對(duì)所有其他表的列使用明確的子集來(lái)完成的。

4、外部聯(lián)結(jié)

許多聯(lián)結(jié)將一個(gè)表中的行與另一個(gè)表中的行相關(guān)聯(lián)。但有時(shí)候會(huì)需要包含沒有關(guān)聯(lián)行的那些行。例如,可能需要使用聯(lián)結(jié)來(lái)完成以下工作:

比如:對(duì)每個(gè)客戶下了多少訂單進(jìn)行計(jì)數(shù),包括那些至今尚未下訂單的客戶;

SELECT customers.cust_id,order_num
from customers LEFT OUTER JOIN orders on customers.cust_id = orders.cust_id

這條SELECT語(yǔ)句使用了關(guān)鍵字OUTER JOIN來(lái)指定聯(lián)結(jié)的類型(而不是在WHERE子句中指定)。但是,與內(nèi)部聯(lián)結(jié)關(guān)聯(lián)兩個(gè)表中的行不同的是,外部聯(lián)結(jié)還包括沒有關(guān)聯(lián)行的行。在使用OUTER JOIN語(yǔ)法時(shí),必須使用RIGHTLEFT關(guān)鍵字
指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表,而LEFT指出的是OUTER JOIN左邊的表)。

使用帶聚集函數(shù)的聯(lián)結(jié):

要檢索所有客戶及每個(gè)客戶所下的訂單數(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

注意點(diǎn):
1.注意所使用的聯(lián)結(jié)類型。一般我們使用內(nèi)部聯(lián)結(jié),但使用外部聯(lián)結(jié)也是有效的。
2.保證使用正確的聯(lián)結(jié)條件,否則將返回不正確的數(shù)據(jù)。
3.應(yīng)該總是提供聯(lián)結(jié)條件,否則會(huì)得出笛卡兒積。
4.在一個(gè)聯(lián)結(jié)中可以包含多個(gè)表,甚至對(duì)于每個(gè)聯(lián)結(jié)可以采用不同的聯(lián)結(jié)類型。雖然這樣做是合法的,一般也很有用,但應(yīng)該在一起測(cè)試它們前,分別測(cè)試每個(gè)聯(lián)結(jié)。這將使故障排除更為簡(jiǎn)單。

到此這篇關(guān)于mysql 子查詢與連接表詳情的文章就介紹到這了,更多相關(guān)mysql 子查詢與連接表內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

美國(guó)服務(wù)器租用

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開通

自選配置、實(shí)時(shí)開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對(duì)1客戶咨詢顧問

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部