国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > SQL Server > 正文

編寫SQL查詢的關鍵—SQL語句的執(zhí)行順序

2019-11-03 08:35:45
字體:
來源:轉載
供稿:網(wǎng)友
   編寫 SQL 語句是每個程序員應該具備的基本功。在實際開發(fā)過程中,需要編寫比較復雜的 SQL 查詢語句是必不可少的,但很多 SQL 書籍上不是簡單的介紹一下就是出最終的查詢語句,編寫復雜 SQL 查詢的具體思路卻沒有多少介紹,這不能不說是一種巨大的遺憾 , 看著一串無比復雜的 SQL 語句,沒有掌握方法的話誰看了都會頭暈 ^-^

回憶一下學習編程語言的經(jīng)歷( C++,java 等),我們一般都是先學習變量的定義,然后是流程控制語句,接著是函數(shù),類等等。但我們在學習 SQL , SQL 書籍上都普遍忽略了一個重要的方面: SQL 語句的執(zhí)行順序。 不知道是什么原因,這一點確實沒被多少書籍提過。掌握了SQL語句的執(zhí)行順序的規(guī)律,就能較輕松的編寫出復雜的 SQL 查詢。

  

SQL 語句的執(zhí)行順序如下:

  

1 、 from 子句組裝來自不同數(shù)據(jù)源的數(shù)據(jù);

2 、 where 子句基于指定的條件對記錄行進行篩選;

3 、 group by 子句將數(shù)據(jù)劃分為多個分組;

4 、使用聚集函數(shù)進行計算;

5 、使用 having 子句篩選分組;

6 、計算所有的表達式;

7 、使用 order by 對結果集進行排序。

  

下面舉一個簡單的例子舉例說明,假設有以下一張表 student :

  

ID
Name
Age

1
Tom
23

2
Jack
25

3
Lucy
15

4
Anay
18

5
Bobby
21


  

要求通過 SQL 語句把年齡大于 20 的學生姓名查出來

  

SQL 語句如下:

  

Select name

From student

Where age>20

結果是:

Tom

Jack

Bobby


  

那對于這個簡單的 SQL 語句,執(zhí)行順序是怎么樣的呢?

1.       from 子句組裝來自不同數(shù)據(jù)源的數(shù)據(jù),簡單點來說就是要確定查詢的數(shù)據(jù)來自哪個表。如果 from 關鍵字后跟的表有兩個或以上,就產(chǎn)生笛卡爾積。

2.       where 子句對每個記錄行進行 篩選,把不符合條件的行篩選掉。

3.       針對符合條件的行執(zhí)行相應的表達式操作,即 select 部分。

  

我們針對前面的寫的 SQL 語句簡單模擬一下執(zhí)行過程:

1. 確定數(shù)據(jù)表,我們能根據(jù) from 子句( From student )確定數(shù)據(jù)是來自下面的的表 student

    

ID
Name
Age

1
Tom
23

2
Jack
25

3
Lucy
15

4
Anay
18

5
Bobby
21


                                    表 1

  

2. 根據(jù) where 子句中的條件( Where age>20 )篩選 記錄行,請留意, where 子句的 篩選是對每一行 from 表中的每一行進行的。

(1)       對于第 1 行

1
Tom
23


  

Age=23>20, 符合條件

  

(2)       對于第 2 行

2
Jack
25


  

Age=25>20, 符合條件

  

(3)       對于第 3 行

3
Lucy
15


  

Age=15<20, 不符合條件

  

(4)       對于第 4 行

4
Anay
18


  

Age=18<20, 不符合條件

  

(5)       對于第 5 行

5
Bobby
21


  

Age=21>20, 符合條件

  

由上述的 (1)(2)(5) 可知,最終符合條件的記錄為下表 2

  

ID
Name
Age

1
Tom
23

2
Jack
25

5
Bobby
21


                 表 2

  

4.       計算所有的表達式,即 Select name 部分,針對表 2 中的數(shù)據(jù),最終符合條件的是 3 行,分別從每一行挑選出需要的字段值 name ,最終的結果如下表 3

Name

Tom

Jack

Bobby


                                    表 3

  

下面舉一般比較復雜的例子,有 3 個表 teacher 表, student 表, tea_stu 關系表:


teacher 表 teaID name age
student 表 stuID name age
teacher_student 表 teaID stuID


要求用一條 sql 查詢出這樣的結果
1. 顯示的字段要有老師 name, 每個老師所帶的學生人數(shù)
2 只列出老師 age 為 45 以下,學生 age 為 12 以上的記錄

  

先準備測試數(shù)據(jù):

  

drop table if exists tea_stu;

drop table if exists teacher;

drop table if exists student;

      create table teacher(teaID int PRimary key,name varchar(50),age int);

      create table student(stuID int primary key,name varchar(50),age int);

      create table tea_stu(teaID int references teacher(teaID),stuID int references student(stuID));

insert into teacher values(1,' Tom',46), (2,' Jack',35) , (3,' Tony',36) , (4,' Lucy',37);

insert into student values(1,' Lili',11), (2,' Anay',15) , (3, 'Bobby',16) , (4, 'Jeff',17);

insert into tea_stu values(1,1), (1,2), (1,3),(2,2), (2,3), (2,4),(3,3), (3,4), (3,1),(4,4), (4,1), (4,2) , (4,3);

  

題目要求是列出 老師所帶的學生數(shù),條件是 老師 age 為 45 以下,學生 age 為 12 以上,最理想的情況是有下面的一個表 , 如圖 1




                                  圖 1

  

如果能構造一個圖 1 的表,那么實現(xiàn)題目要求的 SQL 語句用下面的簡單 SQL 查詢就行:

  

select teacher.name, count(student.name)

from table

where teacher.age<45

   and student.age>12

group by teacher.name;

  

數(shù)據(jù)庫中學生的信息和老師的信息是分別存放在 student, teacher 表中的,信息的關聯(lián)只能依靠 tea_stu ,那么怎么構造圖 1 的表呢?這時候可以用到表的關聯(lián),把這三個表的數(shù)據(jù)關聯(lián)起來, 注意:只要是表的關聯(lián)就會產(chǎn)生笛卡爾積,所以務必把笛卡爾積去掉。 關聯(lián)表的最小粒度關聯(lián)可以 去掉 笛卡爾積,具體的查詢語句為:

select teacher.name, teacher.age,student.name,student.age

from teacher,student,tea_stu

where teacher.teaID=tea_stu.teaID

   and student.stuID=tea_stu.stuID

  

     所以綜合以上所述,就能得出最終的查詢語句

  

select teacher.name, count(student.name) student_num

from teacher,student,tea_stu

where teacher.teaID=tea_stu.teaID

   and student.stuID=tea_stu.stuID

   and teacher.age<45

   and student.age>12

group by teacher.name;

  

結果如圖 2 所示:

  


                      圖 2

  




發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 定日县| 武平县| 冕宁县| 临漳县| 东乡| 北海市| 苍溪县| 肃北| 本溪市| 朝阳市| 宜章县| 瑞丽市| 临颍县| 沁阳市| 柘荣县| 台南县| 若尔盖县| 南召县| 潜江市| 平罗县| 临邑县| 浮山县| 宁远县| 库车县| 沁源县| 宁陵县| 安徽省| 苏尼特左旗| 凭祥市| 大姚县| 青浦区| 江都市| 诸暨市| 新沂市| 霍州市| 平原县| 简阳市| 沛县| 普定县| 江陵县| 蒙城县|