1. 程式人生 > >sql中exits和in的區別

sql中exits和in的區別

轉:http://hi.baidu.com/delphi_relive/blog/item/d7c0034a49c4932208f7ef21.html

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 檢查的行進行分組和聚集計算。

   (11) 聚合函式的巢狀使用