国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

如何解析SQL

發(fā)布時(shí)間:2021-09-27 17:43 來(lái)源:億速云 閱讀:0 作者:小新 欄目: Mysql 歡迎投稿:712375056

這篇文章主要為大家展示了“如何解析SQL”,內容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習一下“如何解析SQL”這篇文章吧。

1、 SQL 是一種聲明式語(yǔ)言

首先要把這個(gè)概念記在腦中:“聲明”。 SQL 語(yǔ)言是為計算機聲明了一個(gè)你想從原始數據中獲得什么樣的結果的一個(gè)范例,而不是告訴計算機如何能夠得到結果。這是不是很棒?

(譯者注:簡(jiǎn)單地說(shuō),SQL 語(yǔ)言聲明的是結果集的屬性,計算機會(huì )根據 SQL 所聲明的內容來(lái)從數據庫中挑選出符合聲明的數據,而不是像傳統編程思維去指示計算機如何操作。)

SELECT first_name, last_name FROM employees WHERE salary > 100000

上面的例子很容易理解,我們不關(guān)心這些雇員記錄從哪里來(lái),我們所需要的只是那些高薪者的數據(譯者注: salary>100000 )。

我們從哪兒學(xué)習到這些?

如果 SQL 語(yǔ)言這么簡(jiǎn)單,那么是什么讓人們“聞 SQL 色變”?主要的原因是:我們潛意識中的是按照命令式編程的思維方式思考問(wèn)題的。就好像這樣:“電腦,先執行這一步,再執行那一步,但是在那之前先檢查一下是否滿(mǎn)足條件 A 和條件 B ”。例如,用變量傳參、使用循環(huán)語(yǔ)句、迭代、調用函數等等,都是這種命令式編程的思維慣式。

2、 SQL 的語(yǔ)法并不按照語(yǔ)法順序執行

SQL 語(yǔ)句有一個(gè)讓大部分人都感到困惑的特性,就是:SQL 語(yǔ)句的執行順序跟其語(yǔ)句的語(yǔ)法順序并不一致。SQL 語(yǔ)句的語(yǔ)法順序是:

  • SELECT[DISTINCT]

  • FROM

  • WHERE

  • GROUP BY

  • HAVING

  • UNION

  • ORDER BY

為了方便理解,上面并沒(méi)有把所有的 SQL 語(yǔ)法結構都列出來(lái),但是已經(jīng)足以說(shuō)明 SQL 語(yǔ)句的語(yǔ)法順序和其執行順序完全不一樣,就以上述語(yǔ)句為例,其執行順序為:

  • FROM

  • WHERE

  • GROUP BY

  • HAVING

  • SELECT

  • DISTINCT

  • UNION

  • ORDER BY

關(guān)于 SQL 語(yǔ)句的執行順序,有三個(gè)值得我們注意的地方:

1、 FROM 才是 SQL 語(yǔ)句執行的第一步,并非 SELECT 。數據庫在執行 SQL 語(yǔ)句的第一步是將數據從硬盤(pán)加載到數據緩沖區中,以便對這些數據進(jìn)行操作。(譯者注:原文為“The first thing that happens is loading data from the disk into memory, in order to operate on such data.”,但是并非如此,以 Oracle 等常用數據庫為例,數據是從硬盤(pán)中抽取到數據緩沖區中進(jìn)行操作。)

2、 SELECT 是在大部分語(yǔ)句執行了之后才執行的,嚴格的說(shuō)是在 FROM 和 GROUP BY 之后執行的。理解這一點(diǎn)是非常重要的,這就是你不能在 WHERE 中使用在 SELECT 中設定別名的字段作為判斷條件的原因。

SELECT A.x + A.y AS z
FROM A
WHERE z = 10 -- z 在此處不可用,因為SELECT是最后執行的語(yǔ)句!

如果你想重用別名z,你有兩個(gè)選擇。要么就重新寫(xiě)一遍 z 所代表的表達式:

SELECT A.x + A.y AS z
FROM AWHERE (A.x + A.y) = 10

…或者求助于衍生表、通用數據表達式或者視圖,以避免別名重用。請看下文中的例子。

3、 無(wú)論在語(yǔ)法上還是在執行順序上, UNION 總是排在在 ORDER BY 之前。很多人認為每個(gè) UNION 段都能使用 ORDER BY 排序,但是根據 SQL 語(yǔ)言標準和各個(gè)數據庫 SQL 的執行差異來(lái)看,這并不是真的。盡管某些數據庫允許 SQL 語(yǔ)句對子查詢(xún)(subqueries)或者派生表(derived tables)進(jìn)行排序,但是這并不說(shuō)明這個(gè)排序在 UNION 操作過(guò)后仍保持排序后的順序。

注意:并非所有的數據庫對 SQL 語(yǔ)句使用相同的解析方式。如 、PostgreSQL和 SQLite 中就不會(huì )按照上面第二點(diǎn)中所說(shuō)的方式執行。

我們學(xué)到了什么?

既然并不是所有的數據庫都按照上述方式執行 SQL 預計,那我們的收獲是什么?我們的收獲是永遠要記得: SQL 語(yǔ)句的語(yǔ)法順序和其執行順序并不一致,這樣我們就能避免一般性的錯誤。如果你能記住 SQL 語(yǔ)句語(yǔ)法順序和執行順序的差異,你就能很容易的理解一些很常見(jiàn)的 SQL 問(wèn)題。

當然,如果一種語(yǔ)言被設計成語(yǔ)法順序直接反應其語(yǔ)句的執行順序,那么這種語(yǔ)言對程序員是十分友好的,這種編程語(yǔ)言層面的設計理念已經(jīng)被微軟應用到了 LINQ 語(yǔ)言中。

3、 SQL 語(yǔ)言的核心是對表的引用(table references)

由于 SQL 語(yǔ)句語(yǔ)法順序和執行順序的不同,很多同學(xué)會(huì )認為SELECT 中的字段信息是 SQL 語(yǔ)句的核心。其實(shí)真正的核心在于對表的引用。

根據 SQL 標準,FROM 語(yǔ)句被定義為:

<from clause> ::= FROM <table reference> [ { <comma> <table reference> }... ]

FROM 語(yǔ)句的“輸出”是一張聯(lián)合表,來(lái)自于所有引用的表在某一維度上的聯(lián)合。我們們慢慢來(lái)分析:

FROM a, b

上面這句 FROM 語(yǔ)句的輸出是一張聯(lián)合表,聯(lián)合了表 a 和表 b 。如果 a 表有三個(gè)字段, b 表有 5 個(gè)字段,那么這個(gè)“輸出表”就有 8 ( =5+3)個(gè)字段。

這個(gè)聯(lián)合表里的數據是 ab,即 a 和 b 的笛卡爾積。換句話(huà)說(shuō),也就是 a 表中的每一條數據都要跟 b 表中的每一條數據配對。如果 a 表有3 條數據, b 表有 5 條數據,那么聯(lián)合表就會(huì )有 15 ( =53)條數據。

FROM 輸出的結果被 WHERE 語(yǔ)句篩選后要經(jīng)過(guò) GROUP BY 語(yǔ)句處理,從而形成新的輸出結果。我們后面還會(huì )再討論這方面問(wèn)題。

如果我們從集合論(關(guān)系代數)的角度來(lái)看,一張數據庫的表就是一組數據元的關(guān)系,而每個(gè) SQL 語(yǔ)句會(huì )改變一種或數種關(guān)系,從而產(chǎn)生出新的數據元的關(guān)系(即產(chǎn)生新的表)。

我們學(xué)到了什么?

思考問(wèn)題的時(shí)候從表的角度來(lái)思考問(wèn)題提,這樣很容易理解數據如何在 SQL 語(yǔ)句的“流水線(xiàn)”上進(jìn)行了什么樣的變動(dòng)。

4、 靈活引用表能使 SQL 語(yǔ)句變得更強大

靈活引用表能使 SQL 語(yǔ)句變得更強大。一個(gè)簡(jiǎn)單的例子就是 JOIN 的使用。嚴格的說(shuō) JOIN 語(yǔ)句并非是 SELECT 中的一部分,而是一種特殊的表引用語(yǔ)句。 SQL 語(yǔ)言標準中表的連接定義如下:

<table reference> ::=    <table name>
  | <derived table>
  | <joined table>

就拿之前的例子來(lái)說(shuō):

FROM a, b

a 可能輸如下表的連接:

a1 JOIN a2 ON a1.id = a2.id

將它放到之前的例子中就變成了:

FROM a1 JOIN a2 ON a1.id = a2.id, b

盡管將一個(gè)連接表用逗號跟另一張表聯(lián)合在一起并不是常用作法,但是你的確可以這么做。結果就是,最終輸出的表就有了 a1+a2+b 個(gè)字段了。

(譯者注:原文這里用詞為 degree ,譯為維度。如果把一張表視圖化,我們可以想象每一張表都是由橫縱兩個(gè)維度組成的,橫向維度即我們所說(shuō)的字段或者列,英文為columns;縱向維度即代表了每條數據,英文為 record ,根據上下文,作者這里所指的應該是字段數。)

在 SQL 語(yǔ)句中派生表的應用甚至比表連接更加強大,下面我們就要講到表連接。

我們學(xué)到了什么?

思考問(wèn)題時(shí),要從表引用的角度出發(fā),這樣就很容易理解數據是怎樣被 SQL 語(yǔ)句處理的,并且能夠幫助你理解那些復雜的表引用是做什么的。

更重要的是,要理解 JOIN 是構建連接表的關(guān)鍵詞,并不是 SELECT 語(yǔ)句的一部分。有一些數據庫允許在 INSERT 、 UPDATE 、 DELETE 中使用 JOIN 。

5、 SQL 語(yǔ)句中推薦使用表連接

我們先看看剛剛這句話(huà):

FROM a, b

高級 SQL 程序員也許學(xué)會(huì )給你忠告:盡量不要使用逗號來(lái)代替 JOIN 進(jìn)行表的連接,這樣會(huì )提高你的 SQL 語(yǔ)句的可讀性,并且可以避免一些錯誤。

利用逗號來(lái)簡(jiǎn)化 SQL 語(yǔ)句有時(shí)候會(huì )造成思維上的混亂,想一下下面的語(yǔ)句:

FROM a, b, c, d, e, f, g, h
WHERE a.a1 = b.bxAND a.a2 = c.c1AND d.d1 = b.bc
-- etc...

我們不難看出使用 JOIN 語(yǔ)句的好處在于:

  • 安全。 JOIN 和要連接的表離得非常近,這樣就能避免錯誤。

  • 更多連接的方式,JOIN 語(yǔ)句能去區分出來(lái)外連接和內連接等。

我們學(xué)到了什么?

記著(zhù)要盡量使用 JOIN 進(jìn)行表的連接,永遠不要在 FROM 后面使用逗號連接表。

6、 SQL 語(yǔ)句中不同的連接操作

SQL 語(yǔ)句中,表連接的方式從根本上分為五種:

  • EQUI JOIN

  • SEMI JOIN

  • ANTI JOIN

  • CROSS JOIN

  • DIVISION

EQUI JOIN

這是一種最普通的 JOIN 操作,它包含兩種連接方式:

  • INNER JOIN(或者是 JOIN )

  • OUTER JOIN(包括: LEFT 、 RIGHT、 FULL OUTER JOIN)

用例子最容易說(shuō)明其中區別:

-- This table reference contains authors and their books.
-- There is one record for each book and its author.
-- authors without books are NOT included
author JOIN book ON author.id = book.author_id

-- This table reference contains authors and their books
-- There is one record for each book and its author.
-- ... OR there is an "empty" record for authors without books
-- ("empty" meaning that all book columns are NULL)
author LEFT OUTER JOIN book ON author.id = book.author_id

SEMI JOIN

這種連接關(guān)系在 SQL 中有兩種表現方式:使用 IN,或者使用 EXISTS?!?SEMI ”在拉丁文中是“半”的意思。這種連接方式是只連接目標表的一部分。這是什么意思呢?再想一下上面關(guān)于作者和書(shū)名的連接。我們想象一下這樣的情況:我們不需要作者 / 書(shū)名這樣的組合,只是需要那些在書(shū)名表中的書(shū)的作者信息。那我們就能這么寫(xiě):

-- Using IN
FROM author
WHERE author.id IN (SELECT book.author_id FROM book)

-- Using EXISTS
FROM author
WHERE EXISTS (SELECT 1 FROM book WHERE book.author_id = author.id)

盡管沒(méi)有嚴格的規定說(shuō)明你何時(shí)應該使用 IN ,何時(shí)應該使用 EXISTS ,但是這些事情你還是應該知道的:

  • IN比 EXISTS 的可讀性更好

  • EXISTS 比IN 的表達性更好(更適合復雜的語(yǔ)句)

  • 二者之間性能沒(méi)有差異(但對于某些數據庫來(lái)說(shuō)性能差異會(huì )非常大)

因為使用 INNER JOIN 也能得到書(shū)名表中書(shū)所對應的作者信息,所以很多初學(xué)者機會(huì )認為可以通過(guò) DISTINCT 進(jìn)行去重,然后將 SEMI JOIN 語(yǔ)句寫(xiě)成這樣:

-- Find only those authors who also have books
SELECT DISTINCT first_name, last_name
FROM author
JOIN book ON author.id = book.author_id

這是一種很糟糕的寫(xiě)法,原因如下:

  • SQL 語(yǔ)句性能低下:因為去重操作( DISTINCT )需要數據庫重復從硬盤(pán)中讀取數據到內存中。(譯者注: DISTINCT 的確是一種很耗費資源的操作,但是每種數據庫對于 DISTINCT 的操作方式可能不同)。

  • 這么寫(xiě)并非完全正確:盡管也許現在這么寫(xiě)不會(huì )出現問(wèn)題,但是隨著(zhù) SQL 語(yǔ)句變得越來(lái)越復雜,你想要去重得到正確的結果就變得十分困難。

更多的關(guān)于濫用 DISTINCT 的危害可以參考這篇博文

(http://blog.jooq.org/2013/07/30/10-common-mistakes-java-developers-make-when-writing-sql/)。

ANTI JOIN

這種連接的關(guān)系跟 SEMI JOIN 剛好相反。在 IN 或者 EXISTS 前加一個(gè) NOT 關(guān)鍵字就能使用這種連接。舉個(gè)例子來(lái)說(shuō),我們列出書(shū)名表里沒(méi)有書(shū)的作者:

-- Using IN
FROM author
WHERE author.id NOT IN (SELECT book.author_id FROM book)

-- Using EXISTS
FROM author
WHERE NOT EXISTS (SELECT 1 FROM book WHERE book.author_id = author.id)

關(guān)于性能、可讀性、表達性等特性也完全可以參考 SEMI JOIN。

這篇博文介紹了在使用 NOT IN 時(shí)遇到 NULL 應該怎么辦,因為有一點(diǎn)背離本篇主題,就不詳細介紹,有興趣的同學(xué)可以讀一下

(http://blog.jooq.org/2012/01/27/sql-incompatibilities-not-in-and-null-values/)。

CROSS JOIN

這個(gè)連接過(guò)程就是兩個(gè)連接的表的乘積:即將第一張表的每一條數據分別對應第二張表的每條數據。我們之前見(jiàn)過(guò),這就是逗號在 FROM 語(yǔ)句中的用法。在實(shí)際的應用中,很少有地方能用到 CROSS JOIN,但是一旦用上了,你就可以用這樣的 SQL語(yǔ)句表達:

author CROSS JOIN book

DIVISION

DIVISION 的確是一個(gè)怪胎。簡(jiǎn)而言之,如果 JOIN 是一個(gè)乘法運算,那么 DIVISION 就是 JOIN 的逆過(guò)程。DIVISION 的關(guān)系很難用 SQL 表達出來(lái),介于這是一個(gè)新手指南,解釋 DIVISION 已經(jīng)超出了我們的目的。但是有興趣的同學(xué)還是可以來(lái)看看這三篇文章

(http://blog.jooq.org/2012/03/30/advanced-sql-relational-pision-in-jooq/)

(http://en.wikipedia.org/wiki/Relational_algebra#Division)

(https://www.simple-talk.com/sql/t-sql-programming/pided-we-stand-the-sql-of-relational-pision/)。

推薦閱讀 →_→ 《畫(huà)圖解釋SQL聯(lián)合語(yǔ)句》

我們學(xué)到了什么?

學(xué)到了很多!讓我們在腦海中再回想一下。 SQL 是對表的引用, JOIN 則是一種引用表的復雜方式。但是 SQL 語(yǔ)言的表達方式和實(shí)際我們所需要的邏輯關(guān)系之間是有區別的,并非所有的邏輯關(guān)系都能找到對應的 JOIN 操作,所以這就要我們在平時(shí)多積累和學(xué)習關(guān)系邏輯,這樣你就能在以后編寫(xiě) SQL 語(yǔ)句中選擇適當的 JOIN 操作了。

7、 SQL 中如同變量的派生表

在這之前,我們學(xué)習到過(guò) SQL 是一種聲明性的語(yǔ)言,并且 SQL 語(yǔ)句中不能包含變量。但是你能寫(xiě)出類(lèi)似于變量的語(yǔ)句,這些就叫做派生表:

說(shuō)白了,所謂的派生表就是在括號之中的子查詢(xún):

-- A derived table
FROM (SELECT * FROM author)

需要注意的是有些時(shí)候我們可以給派生表定義一個(gè)相關(guān)名(即我們所說(shuō)的別名)。

-- A derived table with an aliasFROM (SELECT * FROM author) a

派生表可以有效的避免由于 SQL 邏輯而產(chǎn)生的問(wèn)題。舉例來(lái)說(shuō):如果你想重用一個(gè)用 SELECT 和 WHERE 語(yǔ)句查詢(xún)出的結果,這樣寫(xiě)就可以(以 Oracle 為例):

-- Get authors' first and last names, and their age in days
SELECT first_name, last_name, age
FROM (
  SELECT first_name, last_name, current_date - date_of_birth age
  FROM author
)
-- If the age is greater than 10000 days
WHERE age > 10000

需要我們注意的是:在有些數據庫,以及 SQL : 1990 標準中,派生表被歸為下一級——通用表語(yǔ)句( common table experssion)。這就允許你在一個(gè) SELECT 語(yǔ)句中對派生表多次重用。上面的例子就(幾乎)等價(jià)于下面的語(yǔ)句:

WITH a AS (
  SELECT first_name, last_name, current_date - date_of_birth age
  FROM author
)
SELECT *
FROM a
WHERE age > 10000

當然了,你也可以給“ a ”創(chuàng )建一個(gè)單獨的視圖,這樣你就可以在更廣泛的范圍內重用這個(gè)派生表了。更多信息可以閱讀下面的文章(http://en.wikipedia.org/wiki/View_%28SQL%29)。

我們學(xué)到了什么?

我們反復強調,大體上來(lái)說(shuō) SQL 語(yǔ)句就是對表的引用,而并非對字段的引用。要好好利用這一點(diǎn),不要害怕使用派生表或者其他更復雜的語(yǔ)句。

8、 SQL 語(yǔ)句中 GROUP BY 是對表的引用進(jìn)行的操作

讓我們再回想一下之前的 FROM 語(yǔ)句:

FROM a, b

現在,我們將 GROUP BY 應用到上面的語(yǔ)句中:

GROUP BY A.x, A.y, B.z

上面語(yǔ)句的結果就是產(chǎn)生出了一個(gè)包含三個(gè)字段的新的表的引用。我們來(lái)仔細理解一下這句話(huà):當你應用 GROUP BY 的時(shí)候, SELECT 后沒(méi)有使用聚合函數的列,都要出現在 GROUP BY 后面。(譯者注:原文大意為“當你是用 GROUP BY 的時(shí)候,你能夠對其進(jìn)行下一級邏輯操作的列會(huì )減少,包括在 SELECT 中的列”)。

  • 需要注意的是:其他字段能夠使用聚合函數:

SELECT A.x, A.y, SUM(A.z)FROM AGROUP BY A.x, A.y
  • 還有一點(diǎn)值得留意的是: MySQL 并不堅持這個(gè)標準,這的確是令人很困惑的地方。(譯者注:這并不是說(shuō) MySQL 沒(méi)有 GROUP BY 的功能)但是不要被 MySQL 所迷惑。 GROUP BY 改變了對表引用的方式。你可以像這樣既在 SELECT 中引用某一字段,也在 GROUP BY 中對其進(jìn)行分組。

我們學(xué)到了什么?

GROUP BY,再次強調一次,是在表的引用上進(jìn)行了操作,將其轉換為一種新的引用方式。

9、 SQL 語(yǔ)句中的 SELECT 實(shí)質(zhì)上是對關(guān)系的映射

我個(gè)人比較喜歡“映射”這個(gè)詞,尤其是把它用在關(guān)系代數上。(譯者注:原文用詞為 projection ,該詞有兩層含義,第一種含義是預測、規劃、設計,第二種意思是投射、映射,經(jīng)過(guò)反復推敲,我覺(jué)得這里用映射能夠更直觀(guān)的表達出 SELECT 的作用)。一旦你建立起來(lái)了表的引用,經(jīng)過(guò)修改、變形,你能夠一步一步的將其映射到另一個(gè)模型中。 SELECT 語(yǔ)句就像一個(gè)“投影儀”,我們可以將其理解成一個(gè)將源表中的數據按照一定的邏輯轉換成目標表數據的函數。

通過(guò) SELECT語(yǔ)句,你能對每一個(gè)字段進(jìn)行操作,通過(guò)復雜的表達式生成所需要的數據。

SELECT 語(yǔ)句有很多特殊的規則,至少你應該熟悉以下幾條:

  1. 你僅能夠使用那些能通過(guò)表引用而得來(lái)的字段;

  2. 如果你有 GROUP BY 語(yǔ)句,你只能夠使用 GROUP BY 語(yǔ)句后面的字段或者聚合函數;

  3. 當你的語(yǔ)句中沒(méi)有 GROUP BY 的時(shí)候,可以使用開(kāi)窗函數代替聚合函數;

  4. 當你的語(yǔ)句中沒(méi)有 GROUP BY 的時(shí)候,你不能同時(shí)使用聚合函數和其它函數;

  5. 有一些方法可以將普通函數封裝在聚合函數中;

  6. ……

一些更復雜的規則多到足夠寫(xiě)出另一篇文章了。比如:為何你不能在一個(gè)沒(méi)有 GROUP BY 的 SELECT 語(yǔ)句中同時(shí)使用普通函數和聚合函數?(上面的第 4 條)

原因如下:

  1. 憑直覺(jué),這種做法從邏輯上就講不通。

  2. 如果直覺(jué)不能夠說(shuō)服你,那么語(yǔ)法肯定能。 SQL : 1999 標準引入了 GROUPING SETS,SQL: 2003 標準引入了 group sets : GROUP BY() 。無(wú)論什么時(shí)候,只要你的語(yǔ)句中出現了聚合函數,而且并沒(méi)有明確的 GROUP BY 語(yǔ)句,這時(shí)一個(gè)不明確的、空的 GROUPING SET 就會(huì )被應用到這段 SQL 中。因此,原始的邏輯順序的規則就被打破了,映射(即 SELECT )關(guān)系首先會(huì )影響到邏輯關(guān)系,其次就是語(yǔ)法關(guān)系。(譯者注:這段話(huà)原文就比較艱澀,可以簡(jiǎn)單理解如下:在既有聚合函數又有普通函數的 SQL 語(yǔ)句中,如果沒(méi)有 GROUP BY 進(jìn)行分組,SQL 語(yǔ)句默認視整張表為一個(gè)分組,當聚合函數對某一字段進(jìn)行聚合統計的時(shí)候,引用的表中的每一條 record 就失去了意義,全部的數據都聚合為一個(gè)統計值,你此時(shí)對每一條 record 使用其它函數是沒(méi)有意義的)。

糊涂了?是的,我也是。我們再回過(guò)頭來(lái)看點(diǎn)淺顯的東西吧。

我們學(xué)到了什么?

SELECT 語(yǔ)句可能是 SQL 語(yǔ)句中最難的部分了,盡管他看上去很簡(jiǎn)單。其他語(yǔ)句的作用其實(shí)就是對表的不同形式的引用。而 SELECT 語(yǔ)句則把這些引用整合在了一起,通過(guò)邏輯規則將源表映射到目標表,而且這個(gè)過(guò)程是可逆的,我們可以清楚的知道目標表的數據是怎么來(lái)的。

想要學(xué)習好 SQL 語(yǔ)言,就要在使用 SELECT 語(yǔ)句之前弄懂其他的語(yǔ)句,雖然 SELECT 是語(yǔ)法結構中的第一個(gè)關(guān)鍵詞,但它應該是我們最后一個(gè)掌握的。

10、 SQL 語(yǔ)句中的幾個(gè)簡(jiǎn)單的關(guān)鍵詞: DISTINCT , UNION , ORDER BY 和 OFFSET

在學(xué)習完復雜的 SELECT 豫劇之后,我們再來(lái)看點(diǎn)簡(jiǎn)單的東西:

  • 集合運算( DISTINCT 和 UNION )

  • 排序運算( ORDER BY,OFFSET…FETCH)

集合運算( set operation):

集合運算主要操作在于集合上,事實(shí)上指的就是對表的一種操作。從概念上來(lái)說(shuō),他們很好理解:

  • DISTINCT 在映射之后對數據進(jìn)行去重

  • UNION 將兩個(gè)子查詢(xún)拼接起來(lái)并去重

  • UNION ALL 將兩個(gè)子查詢(xún)拼接起來(lái)但不去重

  • EXCEPT 將第二個(gè)字查詢(xún)中的結果從第一個(gè)子查詢(xún)中去掉

  • INTERSECT 保留兩個(gè)子查詢(xún)中都有的結果并去重

排序運算( ordering operation):

排序運算跟邏輯關(guān)系無(wú)關(guān)。這是一個(gè) SQL 特有的功能。排序運算不僅在 SQL 語(yǔ)句的最后,而且在 SQL 語(yǔ)句運行的過(guò)程中也是最后執行的。使用 ORDER BY 和 OFFSET…FETCH 是保證數據能夠按照順序排列的最有效的方式。其他所有的排序方式都有一定隨機性,盡管它們得到的排序結果是可重現的。

OFFSET…SET是一個(gè)沒(méi)有統一確定語(yǔ)法的語(yǔ)句,不同的數據庫有不同的表達方式,如 MySQL 和 PostgreSQL 的 LIMIT…OFFSET、SQL Server 和 Sybase 的 TOP…START AT 等。具體關(guān)于 OFFSET..FETCH 的不同語(yǔ)法可以參考這篇文章

(http://www.jooq.org/doc/3.1/manual/sql-building/sql-statements/select-statement/limit-clause/)。

讓我們在工作中盡情的使用 SQL!

正如其他語(yǔ)言一樣,想要學(xué)好 SQL 語(yǔ)言就要大量的練習。上面的 10 個(gè)簡(jiǎn)單的步驟能夠幫助你對你每天所寫(xiě)的 SQL 語(yǔ)句有更好的理解。另一方面來(lái)講,從平時(shí)常見(jiàn)的錯誤中也能積累到很多經(jīng)驗。下面的兩篇文章就是介紹一些 JAVA 和其他開(kāi)發(fā)者所犯的一些常見(jiàn)的 SQL 錯誤:

  • 10 Common Mistakes Java Developers Make when Writing SQL

  • 10 More Common Mistakes Java Developers Make when Writing SQL

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

SQL
国产精品久久精品国产| 99久久免费精品国产72精品九九| 亚洲AV无码专区日韩乱码不卡| 精品多毛少妇人妻AV免费久久| 中文字幕高清免费日韩视频在线| 寡妇张开腿让黑人捅爽|