sql查詢語句執行順序詳解

sql查詢語句的處理步驟如下

--查詢組合字段
(5)select (5-2) distinct(5-3) top(<top_specification>)(5-1)<select_list>
--連表
(1)from (1-J)<left_table><join_type> join <right_table> on <on_predicate>
        (1-A)<left_table><apply_type> apply <right_table_expression> as <alias>
        (1-P)<left_table> pivot (<pivot_specification>) as <alias>
        (1-U)<left_table> unpivot (<unpivot_specification>) as <alias>
--查詢條件
(2)where <where_pridicate>
--分組
(3)group by <group_by_specification>
--分組條件
(4)having<having_predicate>
--排序
(6)order by<order_by_list>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

說明: 
1、順序爲有1-6,6個大步驟,然後細分,5-1,5-2,5-3,由小變大順序,1-J,1-A,1-P,1-U,爲並行次序。如果不夠明白,接下來我在來個流程圖看看。

2、執行過程中也會相應的產生多個虛擬表(下面會有提到),以配合最終的正確查詢。

sql查詢語句處理步驟流程圖

這裏寫圖片描述

準備實例,創建表,插入數據,寫要分析的實例查詢語句

1.首先創建兩個表

這裏寫圖片描述

2.創建兩個表,並插入表數據,腳本如下

USE [test]
GO
/****** Object:  Table [dbo].[Member]    Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Member](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](30) NULL,
    [phone] [varchar](15) NULL,
 CONSTRAINT [PK_MEMBER] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Order]    Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Order](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [member_id] [int] NULL,
    [status] [int] NULL,
    [createTime] [datetime] NULL,
 CONSTRAINT [PK_ORDER] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET IDENTITY_INSERT [dbo].[Member] ON 

GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (1, N'張龍豪', N'18501733702')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (2, N'Jim', N'15039512688')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (3, N'Tom', N'15139512854')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (4, N'Lulu', N'15687425583')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (5, N'Jick', N'13528567445')
GO
SET IDENTITY_INSERT [dbo].[Member] OFF
GO
SET IDENTITY_INSERT [dbo].[Order] ON 

GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (1, 1, 3, CAST(0x0000A40900B3BBFB AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (2, 2, 1, CAST(0x0000A40900B3CEF2 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (3, 3, 4, CAST(0x0000A40900B3D2D0 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (4, 4, 0, CAST(0x0000A40900B3D660 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (5, 5, 1, CAST(0x0000A40900B3D9B9 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (6, 6, 2, CAST(0x0000A40900B3DFEA AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (7, NULL, 0, CAST(0x0000A40900E34971 AS DateTime))
GO
SET IDENTITY_INSERT [dbo].[Order] OFF
GO
ALTER TABLE [dbo].[Order] ADD  DEFAULT (getdate()) FOR [createTime]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'編號' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'姓名' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'Name'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'電話' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'phone'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'會員表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'編號' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'會員編號' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'member_id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'訂單狀態' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'status'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'下單日期' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'createTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'訂單表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order'
GO
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

3.編寫咱們要解析的查詢語句,即本篇要查詢的實例語句。

select top(4)  status , max(m.id) as maxMemberID
from [dbo].[Member] as m right outer join [dbo].[Order] as o 
on m.id=o.member_id 
where m.id>0
group by status 
having status>=0
order by maxMemberID asc
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

實例語句分步驟分析

1.從from開始

1.1 加載左表

from [dbo].[Member] as m 
  • 1

查詢結果:member表中的所有數據

1.2 這裏應該是 right outer join ,但是這裏在sql中被定義分解爲2個步驟,即join ,right outer join 。表達式關鍵字從左到右,依次執行。

join [dbo].[Order] as o 
  • 1

查詢結果:存入虛擬表vt1,爲兩個表的笛卡爾集合。這裏你或許不明白什麼叫笛卡爾集合,我打個比方給說說,還望不要嫌棄,就是小朋友握手問題,A班裏有3個學生(看作一個表的三條數據),B班裏有2個學生(看作另外一個表的2條數據).B班小朋友跟A班小朋友搞聯歡晚會,首先要每個人都要確保跟另外一個班的同學我一下手,那麼交叉出來的集合就是(2*3=6)有6條不同的軌跡。這個軌跡的集合就是笛卡爾集合。如果你還不明白,我再說下,就是m(5條數據)表中的第一條數據跟o(7條數據)表中的所有數據握下手,有7條,然後依次類推共有35條不同的數據。這裏的null值也是要加進來的。

1.3、on 篩選器

on m.id=o.member_id 
  • 1

查詢結果如下: 
這裏寫圖片描述

從上一步的笛卡爾集中的35條數據中刪除掉不匹配的行,得到5條數據,存入虛擬表Vt2。

1.4 、添加外部行(outer row)

right outer join [dbo].[Order] as o 
  • 1

查詢結果如下: 
這裏寫圖片描述

右表(order)作爲保留表,把剩餘的數據重新添加到上一步的虛擬表vt2中,生成虛擬表vt3。

2. where 階段

where m.id>0
  • 1

查詢結果:存入虛擬表vt4,爲篩選的條件爲true的結果集,這裏加入一個記憶點,就是,where的篩選刪除爲永久的,而on的篩選刪除爲暫時的,因爲on篩選過後,有可能會經過outer添加外部行,重新把數據加載回來,而where則不能。

3.group by分組

group by status
  • 1

查詢結果:存入vt5,以status列的數值開始分組,即status列,值一樣的分爲一組,這裏的兩個null在三值邏輯中被視爲true。三值邏輯:true,false,null。此三值,null爲未知,是數據的邏輯特色,有的地方兩個null相等爲ture,在有些地方則爲false。這個你百度下看看有很多講解。

4.having 篩選

having status>=0
  • 1

查詢結果:篩選分好組的組數據,把不滿足條件的刪除掉

5.select 查詢挑揀計算列

5.1、計算表達式

select status , max(m.id)
  • 1

查詢結果:從分過組的數據中計算各個組中的最大m.id,列出要篩選顯示的列。

5.2、distinct過濾重複 
5.3、top 結合order by 篩選 多少行,但這裏的數據沒有排序只是把多少行數據列出來而已。

6.order by

排序顯示

至此,一個完整的sql查詢執行完畢。 
希望能對大家有所幫助

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章