一、連接查詢簡介
連接查詢中用來連接連個表的條件稱為連接條件或連接謂詞。其形式為:
[<表1>].<列名1><連接運算符>[<表2>].<列2>
常見的連接運算符包括
1、比較運算符:=、>、<、>=、<=、!=、between和and。
2、邏輯運算符:not、and、or。
3、使用between和and連接查詢形式為[<表1>].<列名1><between>[<表2>].<列名2>and[<表2>].<列名3>。
二、連接按照結果集分類
1、內連接:表中的行互相連接。結果集的行數等於每個表滿足條件的行數的乘積,參與連接的表示平等的。
2、外連接:參與連接的表有主次之分,主表的每一行數據去匹配從表的數據列,符合連接條件的數據將直接返回到結果集中,不符合連接條件的數據列將以null填充后返回到結果集中,其中外連接又分左外連接、右外連接和全連接3種。
(一)、等值連接查詢
select p.*,c.* from country as c,person as p where c.countryid = p.countryid
等上面的等值連接中,兩張表都有countryid字段,因此查出來的結果中就會有兩列countryid
(二)、在等值結果中消除數據就是自然連接
select p.name,c.countryname from country as c,person as p where c.countryid = p.countryid
(三)、自身連接
一個數據表自己與自己建立連接稱為自身連接
三、內連接查詢
1、內連接查詢的語法結構如下:
select <屬性或表達式列表> from <表名> [inner] join <表名> on <連接條件> [ where <限定條件> ]
inner可以省略,當只見到join時就是省略了inner。內連接就是傳統的連接操作,這里用on子句指定連接條件,用where子句指定其他限定條件:
select p.name,c.countryname from country as c inner join person p on p.countryid = c.countryid
四、左外連接查詢
1、左外連接查詢的語法結構:
select <屬性或表達式列表> from <表名> left outer join <表名> on <連接條件> [ where <限定條件> ]
如:
select p.name,c.countryname from country as c left join person p on p.countryid = c.countryid
在結果表中包含第一個表中滿足條件的所有記錄,如果是在連接連接上匹配的記錄,則第二個表返回相應值,否則第二個表返回null。也就是說,不管第二個表有沒有記錄都會第一個表的所有字段都會返回,這就是外連接與內連接的區別。
五、右外連接查詢
1、右外連接查詢的語法結構如下:
select <屬性或表達式列表> from <表名> right outer join <表名> on <連接條件> [ where <限定條件> ]
如:
select p.name,c.countryname from country as c right join person p on p.countryid = c.countryid
在結果表中包含第二個表中滿足條件的所有記錄。如果是在連接條件上匹配的記錄,則第一個表返回相應值,否則第一個表返回null。
六、全外連接查詢
1、全外連接查詢的語法結構如下:
select <屬性或表達式列表> from <表名> full outer join <表名> on <連接條件> where <限定條件>]
如:
select p.name,c.countryname from country as c full join person p on p.countryid = c.countryid
在結果表中包含兩個表中滿足條件的所有記錄。如果是在連接條件上匹配的元組,則另一個表返回相應則,沒有則返回null。
七、交叉連接
交叉連接Corss join,用於將第一張表的所有記錄與第二張表的所有記錄組合一次並返回,這個東西在生成測試數據庫時很有用,例如,你定義7個姓,7個名,再交叉連接就能夠產生49條記錄。
如有如下表:姓氏表
名字表:
執行如下SQL語句:
select LastName + firstname from name2 cross join name1
結果如下:
8、聯合查詢union(union all)
union是一個特殊的運算符,用於將兩個或兩個以上的查詢產生一個結果集。join將信息水平連接(添加更多列),而union將信息垂直連接(添加更多行)。
當使用union處理查詢時,要注意以下幾個關鍵點。
(1)、所有union的查詢必須在select列表中有相同的列數。即如果第一個查詢有3個列數,第二個查詢也要只有3個列數。
(2)、union返回結果的標題集僅從第一個查詢中獲得,無論第二個查詢如何命名或取別名都不會更改。
(3)、查詢中對應的列的數據類型必須隱式一致。注意不要求完全一致,只需要隱式一致。
(4)、與其他非union不同,union的默認返回選項為distinct,而不是all。union all語句與union的不同點僅僅在於遇到相同的記錄,全部保留而已。
例如還是用第7條的例子,執行如下語句:
select * from name1 union select * from name2
返回結果為:
由於union默認是distinct查詢,因此想要獲得所有的記錄時,可以用union all,這樣就算上述例子中兩個表都有'王',也會兩條記錄一起返回。
現在來看一下綜合示例:
為了展示一下,建了兩張表,並添加了幾條記錄,如下:
person表
country表
1、查詢一個列表,該列表要包含國家名稱列表與該國家下的person總數。
select c.countryname,count(p.id) from country as c inner join person as p on c.countryid = p.countryid group by c.countryname
輸出結果:
現在在來加一個條件,要求人口數按升序排列:
select c.countryname,count(p.id) as co from country as c inner join person as p on c.countryid = p.countryid group by c.countryname order by co asc
輸出結果:
再加一個條件,要求只輸出person數大於2的記錄:
select c.countryname,count(p.id) as co from country as c inner join person as p on c.countryid = p.countryid group by c.countryname having count(p.id) > 2 order by co asc
輸出結果為: