sql中exits和in的區別
in 和 exists也是很好區別的.
in 是一個集合運算子.
a in {a,c,d,s,d....}
這個運算中,前面是一個元素,後面是一個集合,集合中的元素型別是和前面的元素一樣的.
而exists是一個存在判斷,如果後面的查詢中有結果,則exists為真,否則為假.
in 運算用在語句中,它後面帶的select 一定是選一個欄位,而不是select *.
比如說你要判斷某班是否存在一個名為"小明"的學生,你可以用in 運算:
"小明" in (select sname from student)
這樣(select sname from student) 返回的是一個全班姓名的集合,in用於判斷"小明"是否為此集合中的一個數據;
同時,你也可以用exists語句:
exists (select * from student where sname="小明")
這兩個涵數是差不多的, 但是由於優化方案的不同, 通常NOT EXISTS要比NOT IN 要快, 因為NOT EXISTS可以使用結合演算法而NOT IN 就不行了,而EXISTS則不如IN快, 因為這時候IN可能更多的使用結合演算法.
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
這句相當於
select * from 表A where id in (select id from 表B)
對於表A的每一條資料,都執行select * from 表B where 表B.id=表A.id的存在性判斷,如果表B中存在表A當前行相同的id,則exists為真,該行顯示,否則不顯示
exits適合內大外小的查詢,in適合內小外大的查詢
IN
確定給定的值是否與子查詢或列表中的值相匹配。
EXISTS
指定一個子查詢,檢測行的存在。
比較使用 EXISTS 和 IN 的查詢
這個例子比較了兩個語義類似的查詢。第一個查詢使用 EXISTS 而第二個查詢使用 IN。注意兩個查詢返回相同的資訊。
USE pubs
GO
SELECT DISTINCT pub_name
FROM publishers
WHERE EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')
GO
-- Or, using the IN clause:
USE pubs
GO
SELECT distinct pub_name
FROM publishers
WHERE pub_id IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
GO
下面是任一查詢的結果集:
pub_name
----------------------------------------
Algodata Infosystems
New Moon Books
(2 row(s) affected)
exits 相當於存在量詞:表示集合存在,也就是集合不為空只作用一個集合.例如 exist P 表示P不空時為真; not exist P表示p為空時 為真 in表示一個標量和一元關係的關係。例如:s in P表示當s與P中的某個值相等時 為真; s not in P 表示s與P中的每一個值都不相等時 為真
二 、連線查詢
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNoFROM Persons
INNER
JOIN
Orders
ON Persons.Id_P = Orders.Id_P ORDER BY Persons.LastName
不同的 SQL JOIN 返回的結果集不一樣
除了我們在上面的例子中使用的 INNER JOIN(內連線),我們還可以使用其他幾種連線。
下面列出了您可以使用的 JOIN 型別,以及它們之間的差異。
- JOIN: 如果表中有至少一個匹配,則返回行
- LEFT JOIN: 即使右表中沒有匹配,也從左表返回所有的行
- RIGHT JOIN: 即使左表中沒有匹配,也從右表返回所有的行
- FULL JOIN: 只要其中一個表中存在匹配,就返回行
- 註釋:INNER JOIN 與 JOIN 是相同的。
簡而言之 ,就是你希望看到的結果集是怎樣的,如兩個表 person 和 order 連線 :
如果你只想看到person 中 和order 有聯絡的記錄 即 滿足 order.id_p = person.id的記錄其他不匹配的全不顯示 就用 inner join
left join 就是在返回inner join 的結果集的基礎上返回左表 person 表中 其餘的記錄(這些顯示的記錄行所有與order表相關的欄為空,因為它們不滿足匹配關係)
同理 ,right join 和 full join
3)巢狀子查詢
select t.deptno,count(*) from emp t,(select avg(e.sal) avgsal from emp e) a where t.sal>a.avgsal group by t.deptno
where 運算子 (=,<,>,>=,<=,<>) where 運算子 (in,not in,exists,not exists, all,any)
相關子查詢是指引用了父查詢中某些表或某些列的子查詢(但父查詢不能引用子查詢中的表或列)父查詢可以是select,update,delete 子句。
4)sql 中的聚合 函式的巢狀 使用
聚集函式
和大多數其它關係資料庫產品一樣,PostgreSQL 支援聚集函式。一個聚集函式從多個輸入行中計算出一個結果。比如,我們有在一個行集合上計算 count(數目), sum(總和), avg(均值), max(最大值), min(最小值)的函式。
比如,我們可以用下面的語句找出所有低溫中的最高溫度:
SELECT max(temp_lo) FROM weather; max
-----
46
(1 row)如果我們想知道該讀數發生在哪個城市,可能會用:
SELECT city FROM weather WHERE temp_lo = max(temp_lo); -- 錯!不過這個方法不能運轉,因為聚集函式 max 不能用於 WHERE 子句中。存在這個限制是因為 WHERE 子句決定哪些行可以進入聚集階段;因此它必需在聚集函式之前計算。不過,我們可以用其它方法實現這個目的;這裡我們使用子查詢:
SELECT city FROM weather
WHERE temp_lo = (SELECT max(temp_lo) FROM weather); city
---------------
San Francisco
(1 row)這樣做是可以的,因為子查詢是一次獨立的計算,它獨立於外層查詢計算自己的聚集。
聚集同樣也常用於 GROUP BY 子句。比如,我們可以獲取每個城市低溫的最高值:
SELECT city, max(temp_lo)
FROM weather
GROUP BY city; city | max
---------------+-----
Hayward | 37
San Francisco | 46
(2 rows)這樣每個城市一個輸出。每個聚集結果都是在匹配該城市的行上面計算的。我們可以用 HAVING 過濾這些分組:group by 可以沒有 having 過濾 having必須跟在group by的後面
SELECT city, max(temp_lo)
FROM weather
GROUP BY city
HAVING max(temp_lo) < 40; city | max
---------+-----
Hayward | 37
(1 row)這樣就只給出那些 temp_lo 值曾經有低於 40 度的城市。最後,如果我們只關心那些名字以"S"開頭的城市,我們可以用:
SELECT city, max(temp_lo)
FROM weather
WHERE city LIKE 'S%'
GROUP BY city
HAVING max(temp_lo) < 40;語句中的 LIKE 執行模式匹配,在節9.7裡有解釋。
理解聚集和 SQL 的 WHERE 和 HAVING 子句之間的關係非常重要。WHERE 和 HAVING 的基本區別如下:WHERE 在分組和聚集計算之前選取輸入行(它控制哪些行進入聚集計算),而 HAVING 在分組和聚集之後選取輸出行。因此,WHERE 子句不能包含聚集函式;因為試圖用聚集函式判斷那些行將要輸入給聚集運算是沒有意義的。相反,HAVING 子句總是包含聚集函式。當然,你可以寫不使用聚集的 HAVING 子句,但這樣做沒什麼好處,因為同樣的條件可以更有效地用於 WHERE 階段。
在前面的例子裡,我們可以在 WHERE 裡應用城市名稱限制,因為它不需要聚集。這樣比在 HAVING 裡增加限制更加高效,因為我們避免了為那些未通過 WHERE 檢查的行進行分組和聚集計算。