SQL Server 免費下載
SQL有:
DML操作語言→新增,修改,刪除,查詢
DDL定義(不涉及資料本身)→Creat,Alter,Drop
DCL控制(不涉及資料本身)→管理(DBA控制管理人員在學的)
select 欄位清單
from 資料表來源
where 搜尋條件
group by 欄位清單
having 搜尋條件
order by 欄位清單
--撰寫順序
--select
--from
--where
--group by
--having
--order by
--執行順序
--from
--where
--group by
--having
--select
--order by
select 欄位
from 表
select 姓名 from 學生 從學生資料表裡面,選擇性名這個欄位
select * from 學生 從學生資料表裡面,選擇全部欄位
select 姓名 as Name from 學生 把姓名欄位取別名叫做Name
datediff(單位,起始,結束) DATEDIFF(year,生日,getdate())
select * from 員工
where 薪水>=50000
模糊查詢% = access的*
select *
from 教授
where 科系 like 'C%'
模糊查詢_ = access的?
select *
from 教授
where 科系 like 'C_' 限定兩個字,並且C開頭
select *
from 教授
where 科系 like '[a-e]%' 選出a~e開頭
select *
from 教授
where 科系 like '[^a-e]%' 選出"除了"a~e開頭的
between and 用法
select * from 員工
where 薪水>=20000 and 薪水<=50000
select * from 員工
where 薪水 between 20000 and 50000
in後面接資料集合,必須放在where後
select * from 課程
where 課程編號='CS203' OR 課程編號='CS213'
select * from 課程
where 課程編號 in ('CS203','CS213','CS283','CS111')
--count算共有幾筆資料,會忽略null值
select count(*) as 學生人數 from 學生
--統計姓名欄位共有幾筆資料
select count(姓名) as 學生人數 from 學生
--sum
select sum(薪水) as 薪水總額 from 員工
--avg
select avg(薪水) as 薪水平均 from 員工
--max
select max(薪水) as 最高薪水 from 員工
--min
select min(薪水) as 最低薪水 from 員工
--總和
select count(*) as 員工人數,sum(薪水) as 薪水總額,avg(薪水) as 薪水平均,max(薪水) as 最高薪水, min(薪水) as 最低薪水,
max(薪水)-min(薪水) as 薪水差距
from 員工
--distunct 秀出全部的資料,把重複的去掉
select distinct 學分 from 課程
--group by 把相同的做群組
select 學分 from 課程
group by 學分
--having後面不可加as名稱
--如果沒寫group by就不能用having
select 學號,count(*) as 選課樹小於3
from 班級
group by 學號
having count(*)>3
--order by排序+欄位(由小到大,順排) 寫在最後面
--後面可以加as 名稱 但必須跟select as一樣
select * from 學生
order by 生日
--order by排序+欄位 desc (由大到小,逆排)
select * from 學生
order by 生日 desc
--先以教授編號排序,如果一樣在以學號做排序
select 教授編號,學號,count(*)
from 班級
group by 教授編號,學號
order by 教授編號 desc,學號 desc
top選出前幾筆資料
select top 2 姓名,薪水 from 員工
找出薪水前兩名的資料(利用order by排好順序,再取出前兩筆)
select top 2 姓名,薪水 from 員工 order by 薪水 desc
with ties找出薪水前兩名的資料(薪水可能有重複,所以用with ties
select top 2 with ties 姓名,薪水 from 員工 order by 薪水 desc
--with rollup(限版本2008以上) (小計,需要有兩個欄位以上)
select 教授編號,課程編號,count(*) as 被選課數
from 班級
group by 教授編號,課程編號 with rollup
--with cube(限版本2008以上) (有以教授的角度,也有課程的角度)
select 教授編號,課程編號,count(*) as 被選課數
from 班級
group by 教授編號,課程編號 with cube
------------
--grouping sets 用grouping sets就不用group by 因為意思一樣
--以課程/教授為角度
select 教授編號,課程編號,count(*) as 被選課數
from 班級
group by grouping sets
(
教授編號,
課程編號,
(教授編號,課程編號),
() --總計
)
合併查詢
inner join
select 欄位
from 表1 inner join 表2
on 表1.key = 表2.key
ex:從學生資料表取出學號,姓名欄位,再從班級資料表取出課程編號與教授編號欄
select 學生.學號,學生.姓名,班級.課程編號,班級.教授編號
from 學生 inner join 班級
on 學生.學號 = 班級.學號
--聯集union
select 姓名 from 員工
union
select 姓名 from 學生
--交集intersect
select 姓名 from 員工
intersect
select 姓名 from 學生
--差集except
select 姓名 from 員工
except
select 姓名 from 學生
--子查詢SubQuery
--查詢某位學生的選課資料
--第一種 合併查詢
select * from
班級 inner join 學生
on 班級.學號=學生.學號
where 學生.姓名='張無忌'
--用子查詢
select * from 班級 where 學號=(select 學號 from 學生 where 學生.姓名='張無忌')
--找那些員工的薪水大於平均薪資
select * from 員工 where 薪水>=(select avg(薪水) from 員工)
--exists 子查詢無法單獨執行 不需要欄位對欄位
--用在不知道欄位
select * from 學生 inner join 班級
on 學生.學號=班級.學號 where 課程編號='CS222'
select * from 學生 where 學號 in(
select 學號 from 班級 where 課程編號='CS222')
select 學生.* from 學生 where exists(
select * from 班級 where 課程編號='CS222' and 學生.學號=班級.學號)
--查詢周杰倫選課的課程資料,先用學生學號關連到班級,再從班級用課程編號關連到課程
--in子查詢跟inner join合併查詢比較 兩者查出來答案一下
select * from 課程 where 課程編號 in
(select 課程編號 from 班級 where 學號 in
(select 學號 from 學生 where 姓名='周杰輪'))
select 課程.* from 課程 inner join 班級 on 課程.課程編號=班級.課程編號
inner join 學生 on 學生.學號=班級.學號
where 學生.姓名='周杰輪'
--反向
--查詢周杰倫沒選的課程
--子查詢
select * from 課程 where 課程編號 not in
(select 課程編號 from 班級 where 學號 in
(select 學號 from 學生 where 姓名='周杰輪'))
--不用子查詢
select 課程.* from 課程
except
select 課程.* from 課程
inner join 班級 on 課程.課程編號=班級.課程編號
inner join 學生 on 學生.學號=班級.學號
where 學生.姓名='周杰輪'
--用exists 檢查子查詢的結果是否會回傳 ,是否存在於子查詢,假如不存在會回傳空白
select * from 課程 where not exists
(select 課程編號 from 班級 where exists
(select 學號 from 學生 where 姓名='周杰輪' and 班級.學號=學生.學號)and 課程.課程編號=班級.課程編號)
--all 拿來做比較,與某種集合比較
--找員工薪水比住在台北員工薪水高的 薪水必須大於台北員工全部人
--通常運算子(>=)後面不能放集合
select * from 員工 where 薪水 >= all(
select 薪水 from 員工 where 城市='台北')
--some或any(T-SQL)
--找員工薪水比住在台北員工薪水高的 只要大於台北員工任一人的薪水就會被列出來
select * from 員工 where 薪水 >= some(
select 薪水 from 員工 where 城市='台北')
--offset 一定要搭配order by
--捨棄前面3個,抓後面
select 身份證字號,姓名,薪水
from 員工
order by 身份證字號
offset 3 rows
--fetch next
--捨棄前面3個,只抓2格
select 身份證字號,姓名,薪水
from 員工
order by 身份證字號
offset 3 rows
fetch next 2 rows only
轉換資料型態
- select cast(要轉換的欄位 as 要轉的資料型態)
- select convert(資料型態,要轉換的欄位,可以放轉換格式代碼也可以不放) from 學生
--null概念與資料轉換
- select 身份證字號,姓名,ISNULL(電話,'尚未填寫'),薪水 from 員工
- select 學號,姓名,ISNULL(生日,'尚未填寫') from 學生 --因為生日是data型態,'尚未填寫'是字串所以會出錯
- select 學號,姓名,ISNULL(cast(生日 as varchar),'尚未填寫') from 學生 --把生日先轉成字串
--CTE查詢
--遞迴方式查詢
with 有名字的教授表
as
(select 教授.*,員工.姓名
from 員工 inner join 教授
on 員工.身份證字號=教授.身份證字號)
select *
from 班級
inner join 學生 on 班級.學號=學生.學號
inner join 課程 on 課程.課程編號=班級.課程編號
inner join 有名字的教授表 on 有名字的教授表.教授編號=班級.教授編號
--------------------------------------------------------------------
--一直呼叫自己
--找出最高定錨之後,再找出第二層,之後再用第二層找出第三層
--一層一層往下找,不會跨層比較
with 主管2 --主管2是自己取的
as(
select 員工字號,姓名,1 as 階層 from 主管 where 主管字號 is null --第一層
union all
select 主管.員工字號,主管.姓名,階層+1 from 主管 inner join 主管2 on 主管.主管字號=主管2.員工字號 --第二層
)
select * from 主管2
order by 階層
留言列表