天天看點

mysql if exists用法_mysql中關于exists的講解

我認為exists文法是mysql中一個很強大的工具,可以簡單地實作某些複雜的資料處理。

下面我談談與exists有關的三個方面。

all 與 any

首先,看到了exists,難免還會想到all和any,它們比exists容易了解一些。all 和 any都能讓一行資料與多行資料進行比較,這是它們的主要功能。

先看eg.1, 顯然select * from T where X < 3結果是1,2;而all要求存在X大于集合{1,2}内的任意元素,即3,4。

同理,對于eg.2,select * from T where X > 1結果是2,3,4;any的要求是存在X大于集合{2,3,4}内的某個元素即可,即3,4。

劃分表

在說exist s之前,再看看一個比較特别的語句,關于表(table)的“劃分”用法。

eg.1

現在要求進行篩選,條件是Id唯一,Date選最近的一次

這種篩選條件潛藏着對于表的劃分要求。以fruitTable為例,需要劃分為2個子表,Id為1的為一個子表、Id為2的為另一個子表,再從各自子表裡面選出時間最大的那個元組。

先看看下面一個錯誤的解法

這周解法在邏輯上有漏洞。它将不同Id的最大時間混在了一起,沒有真正地劃分表格。

再來看看正确的解法

劃分表格的思路是正确的,但問題是怎麼劃分,如果另外建立2個新的table,那這樣顯然太麻煩了,于是有了下面這種寫法。

注意WHERE t2.Id=t1.Id 很巧妙地 對表t2 基于t2.Id=t1.Id這個标準 進行了劃分。可以推導一下,比如周遊表t1,先是第1個元組: 1   蘋果    水果    10     2011-7-1, 可以知道t1.Id=1, 帶入第2個select: (SELECT MAX(Date) FROM fruitTable t2 WHERE t2.Id=1) , 觀察這個select語句的篩選條件WHERE t2.Id=1, 發現它的範圍限定在了Id為1的元組内,聚集函數MAX(Date)傳回Id為1的所有元組中Date最大的值(2011-7-3)。

是以對于表t1, 當t1.Id=1時,隻有Date=2011-7-3的元組才會被選出來;而當tl.Id=2時,第2個select又變為SELECT MAX(Date) FROM fruitTable t2 WHERE t2.Id=2, 返會所有Id=2的元組中Date的最大值(2011-7-2)。

可以發現,表t2是受t1.Id控制的,根據t1.Id的不同而被劃分為不同的子表,這就是表的劃分,并且不需要另外建立新的表。

exists

先說說exists的基本用法

對于exists可以先簡單地了解為if判斷。

比如語句select * from R where exists( select * from S where S.Y='b' and R.Y=S.Y );就可以了解為  從表R中篩選出滿足條件 S.Y='b' and R.Y=S.Y (select * from S where S.Y='b' and R.Y=S.Y) 的元組。

這個性質可以看出2個特性

  • 首先exists()括号内的表不會影響最終傳回的結果。比如上面的例子,傳回的結果始終是關于表R的元組,和表S沒有任何關系
  • 對于exists()語句,關鍵的是括号内的where子句。對于exists( select * from S where S.Y='b' and R.Y=S.Y ) 這種語句,可以直接當作 if( S.Y== 'b' and R.Y ==S.Y )。當然也不是說select不重要,比如exists( select 1 from  S where S.Y='b' and R.Y=S.Y  )是永遠為真的條件。

理清上面2點,我們就更能意識到exists非常像是一個關于條件判斷的語句。

下面例子類似

但僅僅隻有exists還不夠,因為很多其它語句也能實作這個功能,真正強大的是not exists。

找最值

這裡not exists同樣可以看作not if,關鍵是明白哪部分條件被否定(not)。根據之前的理論,這裡條件明顯是t2.Id=t1.Id and t2.Date > t1.Date , 而t2.Id=t1.Id不能作為否定的對象,因為這是必然存在的(自己想想,t1和t2内容一樣),用來限定表t2的範圍(即之前說的劃分子表),再看t2.Date > t1.Date,這才是否定的部分,即對于t2中Id為t1.Id的所有元組的Date都不大于t1.Date,而此時的t1.Date也即最大值。

嵌套not exists 還有更複雜的情況,多層not exists嵌套使用。比如實作關系代數裡的除法運算。

這裡有3個select,2個not exists。

最裡面的not exists是用來否定R2.Y=S.Y and R2.Z=S.Z (因為R1.X=R2.X一定成立,這個是用來劃分子表的), 最外層的not exists就用來表示不存在這個意思,你會發現最後這個句子表達的意思就是關系代數裡面除法的定義。

friedCoder

https://www.cnblogs.com/friedCoder/p/12678145.html

mysql if exists用法_mysql中關于exists的講解