SQL基礎之select

1.認識selectsql

  select的主要語法以下,這個很重要由於只有記住了總體的結構才能應對任何狀況。從中能夠看到select的強大主要就是創建在where、group by、having、order by這4個功能之上。數據庫

select [all | distinct] select_list [into new_table]    [from  table_source] express

[where search_condition]ide

[group by byexpression]      函數

[having search_condition]性能

[order by order_expression [asc|desc] ]網站

再來看這6個關鍵字的執行順序,顯然首先你得找到表取得最原始最龐大的數據,所以是from。接着是where用來進行過濾,而後group by和having開始執行,這樣數據的過濾已經完成因此就是select了,還有一個order by就是最後了。總結起來順序是from、where、group by、having、select、order by。若是再加上其它功能點,完整的執行順序爲from,on,join,where,group by,having,with rollup或cube,select,distinct,order by,top。關於from要注意當爲表使用別名時,一旦使用將不可以再用表名,只能使用as後的別名。where中可使用不少運算符組合過濾條件,系統過濾數據時將按照過濾條件以行爲單位一條條的進行過濾。在運算符中邏輯運算符的優先級爲not、and、or,並且not只能用於簡單條件式,不能用於包含and和or的複雜條件式。spa

  group by爲咱們帶來了很是方便的分組功能,但要注意使用時select中只能是by後面的列名和彙集函數。當以by後面的列進行分組時,若是在select中包括其它的列好比columnA,那麼系統將不知道顯示分組後的columnA集合中的哪一條數據,這就是爲何不能select其它列的緣由。另外還要注意group by後的列名必須使用完整的名字,不能出現as的別名,緣由很簡單就是由於執行順序。having和where很類似,它們均可以對結果進行過濾。它們的區別則有2點:having中能夠包含彙集函數,而where是不容許有彙集函數的;having中出現的列必須是select中存在的,而where則可使用表中的任意列。日誌

  在查詢中,若是要對多表進行查詢可以使用where或錶鏈接來進行關聯。和錶鏈接同樣,聯合查詢也是查詢中頗有效的手段,固然它和錶鏈接有着本質的區別,使用它有3個要注意的地方。首先union聯合的2個select語句,必需要有相同數量的列。在有相同列的狀況下,列還必須擁有類似的數據類型,最後select語句的順序也要相同。它的做用則是將多個select的結果集拼接在一塊兒並一塊兒顯示在結果集上,錶鏈接是將表進行關聯鏈接,而聯合查詢只是聯合了查詢出來的結果集,將這些結果集放到一塊兒顯示而已。使用union會發現它除了去除重複行外,還會對結果集進行一個排序,union all既不會去除重複行也不會對結果進行排序。關於union的用法讀者可本身去寫sql,這裏我要強調的是一個使用union常見的錯誤,數據表sql語句以下所示。code

--建立數據庫
create database testDb  on
(
name=testDb_data,
filename='D:\testDb_data.mdf',
size=4,
filegrowth=10%
)
log on
(
name=testDb_log,
filename='D:\testDb_data.log',
size=2,
filegrowth=10%
)

--建立student表
use testDb
create table student
(
studentId int primary key,
studentName nvarchar(16) not null,
studentAge int default(18),
studentSex nchar(1)
)

create table teacher
(
teacherId int primary key,
teacherName nvarchar(16) not null,
teachClass nvarchar(16)
)

--爲student添加新的一列並添加主外鍵約束
alter table student add
teacherId int,constraint teacher_FK foreign key(teacherId) references teacher(teacherId)
select * from teacher

insert into teacher values(1,'劉老師','安卓')
insert into teacher values(2,'吳老師','網站')
insert into teacher values(3,'王老師','物聯網')

select studentId,studentName  from student 
union all
select teacherId,teacherName from teacher
View Code

若是在上面sql中的union後加上order by teacherId則會出現錯誤,提示上說order by項必須出如今選擇列表中,但是這裏teacherId明明就是選擇列表中的列啊。再仔細看看結果集會發現列上的名字是以第一個select中的列名爲標題的,所以這裏teacherId還真沒有出現選擇列表中。將teacerId改成studentId或studentName將會順利執行,關於結果集讀者可自行去試。

select studentId,studentName  from student 
union all
select teacherId,teacherName from teacher 
order by teacherId

select studentId,studentName  from student 
union all
select teacherId,teacherName from teacher 
order by studentId,studentName

在錯誤提示中還出現了intersect和except運算符,既然遇到了那確定要掌握。這3個運算符一塊兒出現說明它們有着某種緊密的聯繫。union如前面所說是兩個數據集的並集,intersect是兩個結果集的交集,except則是兩個結果集的差集。以上面的表爲例,若是使用intersect結果集將爲空,由於這兩個集合根本就沒有相同的數據集。使用except則返回的是第一個select返回的結果。使用union和except的結果以下所示。

select studentId,studentName  from student 
union
select teacherId,teacherName from teacher 
order by studentId,studentName

select studentId,studentName  from student 
except
select teacherId,teacherName from teacher 
order by studentId,studentName
View Code

         

2.從select into到臨時表

  在實際應用中開發者常常會須要去建立一個臨時的表存儲數據,select into正是扮演着這樣的角色。使用select into要注意建立的表名必須是惟一的,當咱們使用select into建立一個臨時的表時會在當前數據庫中創建一張新表。注意這張表已存在於當前數據庫中,這樣的話開發者還須要手動drop,若是忘記刪除將會致使數據庫中的表愈來愈多,並且頗有可能重名。爲了改進這一缺點,SQL利用了和C#裏的垃圾回收同樣的思想,就是由系統來刪除臨時表,固然咱們也能夠手動刪除。咱們只須要在設置臨時表名前加上#或##,一個#表示本地臨時表,兩個#表示全局臨時表。對於本地臨時表,最重要的特色是建立後只對當前此次會話狀態有效,一次會話狀態指的是客戶端與數據庫引擎的鏈接,這裏客戶端指登入者在數據庫上進行操做的一端,最終執行是須要鏈接數據庫引擎來完成的。好比select * into #table1 from student where studentId<4,執行後在系統數據庫中的tempdb可看到建立的臨時表。而且它的名字頗有意思,sql多是爲了防止重名吧,它還爲咱們建立的本地臨時表又添加了後綴名。當我關掉選項卡後,這個臨時表也就從tempdb中消失了,也就是說本地臨時表它屬於建立它的當前用戶,且只在當前會話狀態下可以使用。全局臨時表建立後,全部用戶均可見,當建立者介紹此次會話時好比我關掉選項卡,會發現全局臨時表和本地臨時表一塊兒被刪了。那是否是說全局臨時表和本地臨時表同樣,也是當前會話狀態結束就被系統刪除呢?答案是否認的,這裏和GC很像,若是沒有其餘任務引用這個全局臨時表,那它就被刪除。但要注意建立着會話狀態存在時,其餘任務可引用它建立的全局臨時表,建立着會話狀態存結束時,其餘任務將不能再引用這個全局臨時表,可是此時若是已有任務引用這個全局臨時表不會刪除,直至沒有任務引用它。另外臨時表並非只有select into能夠建立,咱們也能夠直接使用create table建立。

  建立臨時表和非臨時表相比,有哪些優勢和缺點呢?首先咱們最關注的確定是性能,臨時表有一個特色那就是對它的操做不會記錄日誌文件,而非臨時表則會進行記錄,所以臨時表性能比非臨時表更快。在臨時表中,因爲本地臨時表只對當前用戶的當前會話狀態有效,那麼徹底不須要對本地臨時表進行加鎖,因此從這一點來講本地臨時表比全局臨時表更快。顯然這些性能的提升同時伴隨着某些功能將沒法使用,有利也有弊。臨時表與非臨時表同樣,也能夠創建索引、約束,只是不能創建外鍵約束,對於臨時表和非臨時表咱們均可以使用drop和truncate來刪除表。

相關文章
相關標籤/搜索