主頁 > 資料庫 > SQLServer筆記

SQLServer筆記

2020-09-13 23:29:41 資料庫

------------恢復內容開始------------


-
-----------------------------------------------------SQL陳述句的執行順序------------------------------------------------------------------------

1>From 表
2>where 條件
3>group by 列
4>Having 篩選條件
5>select 5-1>被分組列,聚合函式列5-2>distinct>5-3>top
6>order by 列

-----------------------------------------------------GROUP BY---------------------------------------------------------------------------------

--當使用了分組陳述句(group by)或者是聚合函式的時候,在select的查詢串列中不能再包含其他列名,
-- 除了該列同時也出現了group by字句中,或者該列也包含了在某個聚合函式中
分組查詢語法: SELECT 被分組列, 聚合函式列 FROM 表名 WHERE 普通列 GROUP BY 被分組列 HAVING 被分組列, 聚合函式列 ORDER BY 被分組列, 聚合函式列

----------------------------------------------------------------------------------------------------------------------------------------------

update 表 set 列 (select 列 from 表)--子查詢
delete from 表名 where....----delete陳述句如果不加where條件,表示將表中所有的資料洗掉,加上where條件后,會按照where條件進行洗掉對應的行
insert into 表名(列1,列2,列3) values(值1,值2,值3)

------------------------------------------------建表約束----------------------------------------------------------

create table Employees
(
EmpId int identity(1,1) primary key,
EmpName varchar(50) not null unique check(len(EmpName)>2),
EmpGender char(2) default('男'),
EmpAge int check(EmpAge>0 and EmpAge<120),
EmpEmail varchar(100) unique,
EmpAddress varchar(500) not null
EmpDepId int foreign key references Department(DepId) on delete cascade--on delete cascade級聯洗掉
)
--------------------------------------------------------------------------------------------------------------------------------------
Connection 負責用來連接資料庫
ResultSet 結果集
PreparedStatement 負責用來執行sql陳述句
要用statement類的executeQuery()方法來下達select指令以查詢資料庫
executeQuery()方法會把資料庫回應的查詢結果存放在ResultSet類物件中供我們使用

第一步:加載驅動程式 Class.forName(DRIVER);
第二步:連接資料庫 Connection conn = DriverManager.getConnection(URL, "sa", "123456");
第三步:發送sql陳述句(增刪改) PreparedStatement pst = conn.prepareStatement(sql);
第四步:執行查詢
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("studentName")+"|"+rs.getString("studentAge"));
}

備份資料庫
backup database 資料庫名稱 to disk='路徑'
恢復資料庫
restore detabase 資料庫名稱 from disk='備份路徑'


SQL server中的常用資料型別

1.數字資料型別
整數型
bigint =long
int =int
smallint =shotr
tinyint =byte 0-255
bit 1~0

小數型
decimal
numeric 兩個一樣

貨幣型
money

2.字串型別
char
nchar
varchar
nvarchar
text
ntext
varchar(max)
nvarchar(max)

3.時間型別
datetime

4.二進制
binary 固定長度
vninary 可變長度

-------------------------------------------------------
帶n的和不帶n的區別
char(2) 表示可以儲存兩個位元組,ab,12,胡(英文,數字1個位元組,中文2個位元組)

nchar(2) 表示無論存盤中文還是英文,數字,每個字符都占用兩個位元組,ab,12,胡偉(英文,數字2個位元組,中文2個位元組)

不帶n的這些資料型別,長度最長可以設定為8000,
帶n的這些資料型別,長度最長可以設定為4000

char(8000)
varchar(8000)

nchar(4000)
nvarchar(4000)
-------------------------------------------------------
帶var的和不帶var的區別
nchar 不帶var表示,固定長度
varchar 帶var表示,可變長度

//固定長度,存盤1字符也是要占用10個位元組的,會自動補9個空格
char(10) 1 10位元組
1111111111 10位元組

//可變長度,會根據實際儲存資料的大小動態重新分配存盤空間,相對來說節省存盤空間
varchar(10) 1 1位元組
11111 5位元組

//10,表示最多10個位元組,如果存盤的資料超過了10個位元組,那么無論是固定長度還是可變長度都會報錯的,
-------------------------------------------------------
text 淘汰了,等于varchar(max)
ntext 淘汰了,等于nvarchar(max)

varchar(max) max表示4G
nvarchar(max) max表示4G

-------------------------------------------------------資料庫檔案
資料檔案 主要資料檔案 有且只有一個 .mdf(primary data file 的縮寫)
次要資料檔案 0或者多個 .ndf(primary data file 的縮寫)
日志檔案 無 至少一個 .ldf(log data file 的縮寫)

1. 字串函式:
CHARINDEX CHARINDEX('ab', 'cdab') 回傳 3 回傳'ab'在'cdab'中的位置,
SUBSTRING SUBSTRING('abc', 2, 2) 回傳 'bc' 從第2個位置開始截取長度為2的字串
LEN LEN('1個逗逼') 回傳 4 回傳字串的長度(非位元組長度)
UPPER/LOWER UPPER('aBc')/LOWER('aBc') 回傳'ABC'/'abc' 將字串中的字母轉換為大寫/小寫
LTRIM/RTRIM LTRIM(' abc')/RTRIM('abc ') 回傳'abc'/'abc' 去掉字串左邊/右邊的空格 同時去掉兩邊空格 RTRIM(LTRIM(' abc '))
REPLACE REPLACE('abc', 'b', 'x') 回傳 'axc' 將'abc'中的'b'替換為'x'
STUFF STUFF('abcd', 1, 2, '你好') 回傳 '你好cd' 洗掉從第1個字符開始,長度為2的字串,并插入 你好
2. 日期函式
GETDATE GETDATE() 回傳當前日期
DATEADD DATEADD(mm, -2, GETDATE()) 回傳當前日期-2月
DATEDIFF DATEDIFF(dd, '1989-07-14', GETDATE()) 回傳兩個日期之間的間隔
DATENAME DATENAME(DW, GETDATE()) 回傳 '星期幾' 以字串形式回傳當前日期指定的部分
DATEPART DATEPART(DW, GETDATE()) 回傳 一個星期的第幾天 以整數形式回傳當前日期指定的補分
3. 數學函式
CEILING/FLOOR CEILING(24.1)/FLOOR(24.4) 回傳 25/24 返回大于24.1的最小整數、回傳小于24.1的最大整數
ROUND ROUND(748.35, 1) 回傳 748.40 四舍五入到小數點后1位
4. 系統函式
CONVERT CONVERT(VARCHAR(3), 123) 回傳 '123' 轉換資料型別
DATALENGTH DATALENGTH('1個逗逼') 回傳 7 回傳任何資料型別的位元組數,漢字2位元組

-------------------------------------------------------
--在這里撰寫SQL陳述句命令
--1.創建一個資料庫
create database MyDatabaseOne
--2.洗掉資料庫
drop database MyDatabaseOne
--3.創建資料庫的時候設定一些引數選項
create database MyDatabaseOne
on--指定主檔案的屬性
(
--配置主資料的選項
name='MyDatabaseOne',--住資料檔案的邏輯名稱
filename='E:\MySQLServerDatabase.mdf',--住資料檔案的實際保存路徑
size=5MB,--初始化大小
maxsize=200MB,--最大檔案大小
filegrowth=10%--每次增長

)
log on--指定日志檔案的屬性
(
--配置日志檔案的選項
name='MyDatabaseOne_log',--日志檔案的邏輯名稱
filename='E:\MySQLServerDatabase.ldf',--日志檔案的實際保存路徑
size=5MB,--日志檔案的初始大小
filegrowth=10%--每次增長
)
-------------------------在資料庫中創建一個表-------------------------
--將代碼環境切換到MyDatabaseOne
USE MyDatabaseOne
create table Departments
(
Auto int identity(1,1)primary key,
Departments nvarchar(50) not null,
)
--通過代碼,洗掉master資料庫下的某些表
USE master

--drop database --洗掉資料庫
drop table Table_1--洗掉表
drop table Table_1 where 字句--洗掉表中某一條

---創建一個員工表---
--<員工表>:
USE MyDatabaseOne
GO
create table Employees
(
EmpID int identity(1,1) primary key,//主鍵
EmpIDCard varchar(18) not null,
EmpName nvarchar(50) null,
EmpGender bit not null,
EmpJoinDate datetime,
EmpAge int,
EmpAddress nvarchar(300),
EmpPhone varchar(100),
DeptId int not null,
EmpEmail varchar(100),
)
drop table Employees
use MyDatabaseOne
create table Employees
(
EmpID int identity(1,1) primary key,
EmpIDCard varchar(18) not null,
EmpName nvarchar(50) null,
EmpGender bit not null,
EmpJoinDate datetime,
EmpAge int,
EmpAddress nvarchar(300),
EmpPhone varchar(100),
DeptId int not null,
EmpEmail varchar(100),
)

物體完整性:
primary key//(主鍵)約束 唯一識別每一條記錄的標志,可以由多列共同組成**只能有一個,不許重復,不許為null
identity//(自增)約束 列值自增,一般使用此屬性設定的列作為主鍵identtity(1,1)
unique//(唯一)約束 可以使用unique約束確保在非主鍵列中部存在重復值,但是值可以為null

域完整性:
check(檢查)約束//用于限制列中的值的范圍()
foreign key(外鍵)約束//一個表中的foreign key指向另一個表中的primary key
default(默認值)約束//用于向列種插入默認值default'中國'
not null(非空)約束//用于強制列不接受null值
參考完整性:
參考完整性是指兩個表的主鍵和外鍵的資料對應一致,它建立在外鍵和主鍵的關系之上,在sql server中,參考完整性的作用表現在一下3個方面
1.禁止在子表中添加主表中不存在的記錄
2.禁止修改主表的值
3.禁止洗掉子表中的有對應記錄的主表記錄
用戶自定義完整性:
主要是規則rule、約束constraint和觸發器trigger
StudentNum int references Tb_Student(StudentNum) 引入例子!
-------------------------SQL陳述句入門-------------------------
DDL(資料定義語言,建表,建庫等陳述句)
DML(資料操作語言)
DCL(資料控制語言)

SQL陳述句中字串用 單引號、單等號
SQL陳述句不區分大小寫(取決與排序規則)

-----------------------------------------------------------------------向學生表中插入一條記錄
--insert into 表名(列1,列2,列3) values(值1,值2,值3)
--1,自動編號列,默認就會自動增長,所以不需要(默認情況下也不能向自動編號列插入值)
注意:如果欄位型別為varchar或者datetime,則必須使用單引號引起來
賦值與查看例子
insert into Tb_Teacher(TeacherName,TeacherAge,TeacherSalary,TeacherTel) 插入所有值(沒省略)
values('大蛇丸',25,999999,'15271000220')
select * from Tb_Teacher
insert into Tb_Teacher(TeacherName,TeacherTel) 插入部分值
values('火神','22022022022')
select * from Tb_Teacher
insert into Tb_Teacher
values('八神',25,88888,'11011011011') 插入所有值(省略)
select * from Tb_Teacher


同時插入多行資料
insert into Tb_Student
--values('200709002','凱奇',21,'法國','2007-09-02',3000.5) //values插入值
select '200709002','凱奇',21,'法國','2007-09-02',3000.5 union //select插入值(內容不需要())
select '200709003','saha',25,'印度','2007-09-02',1000.5 union
select '200709004','張小飛',21,'中國','2007-09-02',2000.5 //最后一行不需要union


-----------------------------------------------------------------------強行插入
--啟動自動編號列插入值
--啟動某個表的“自動編號列”手動插入值得功能
set identity_insert Tb_Teacher on
insert into Tb_Teacher(TeacherID,TeacherName,TeacherTel)
values(10086,'移動SB','10086')
set identity_insert Tb_Teacher off
select * from Tb_Teacher

--在SQL陳述句中的直接寫的字串中,如果包含中文,一定在字串前面加N
(因為當排序規則不是簡體中文的時候會亂碼)
例子
values(10086,N'移動SB','102016/7/13086')

-----------------------------------------------------------------------打開和關閉查詢結果視窗:ctrl+r

-----------------------------------------------------------------------更新陳述句:
--update 表名 set 列=新值,列2=新值,....where 條件
--update陳述句如果不加where條件,那么表示對表中所有條件都進行修改,所以一定要加where條件
select * from Tb_Teacher
update Tb_Teacher set TeacherAge=TeacherAge+1,TeacherName = TeacherName+'(男)' where TeacherAge = 26
update Tb_Teacher set Age=30 where Name='大蛇丸' or Age<25
select * from Tb_Teacher

--洗掉資料陳述句
--delete from 表名 where....
--delete陳述句如果不加where條件,表示將表中所有的資料洗掉,加上where條件后,會按照where條件進行洗掉
--洗掉Tb_Teacher表中的所有資料,自動編號沒有回復到默認,仍然繼續編號
delete from Tb_Teacher
select * from Tb_Teacher
insert into Tb_Teacher
values('胡偉',25,200,'15271100220')
select * from Tb_Teacher
insert into Tb_Teacher
values('楊磊',26,300,'15271200220')
insert into Tb_Teacher
values('小軍',27,400,'15271300220')
insert into Tb_Teacher
values('張衡',28,500,'15271400220')

外鍵關系-級聯,
級聯洗掉將先洗掉子表中的相應記錄,再洗掉主表記錄


--truncate table 表名
--如果要洗掉表中全部資料,那么建議使用truncate
--truncate特點:
--1.truncate陳述句不能跟where條件(無法根據條件來洗掉,只能全部洗掉)
--2.truncate同時自動編號恢復到初始值
--3.使用truncate洗掉表中的所有資料要比delete效率高的多的多,
--4.truncate 洗掉資料,不觸發觸發器
------------------------------------------------------------------------------------------------------------------------
use mstanford
drop table Tb_Student
create table Tb_Student
(
StudentNo varchar(20) primary key,
StudentName nvarchar(20) not null,
StudentAge int not null check(StudentAge>=20 and StudentAge<=30),
County nvarchar(20) not null default('中國'),
StuTime datetime not null,
Tuition money not null
)
select * from Tb_Student
update Tb_Student set StuTime='2009-09-01' --更新資料

------------------------增加資料 INSERT INTO
select * from Tb_Student_Coures
insert into Tb_Student_Coures values ('200709003','.net','2009-09-09','通過') --增加資料
insert into Tb_Student_Coures values ('200709004','jap','2009-09-09','NULL')
insert into Tb_Student_Coures values ('200709002','java','2009-09-09','通過')

update Tb_Student_Coures set CouresTime='2008-08-08',Notes='通過'where StudentNo='200709003' --更具條件更新資料


------------------------簡單查詢 SELECT
select * from mstanford.dbo.Tb_Student --查詢資料
select studentno from mstanford.dbo.Tb_Student order by studentno desc --查詢并且按降序排列 ASC(縮寫ascending)表示升序 DESC(縮寫descending)表示降序
insert into mstanford.dbo.Tb_Student_Coures values('200709004','jsp','2008-08-08','取消考試')--增加資料
insert into mstanford.dbo.Tb_Student_Coures values('200709004','java',2008-01-02,'NULL')
select StudentNo,Notes from mstanford.dbo.Tb_Student_Coures--查詢多列資料
select * from mstanford.dbo.Tb_Student_Coures--查看所有資料簡寫
select SCNo,StudentNo,CouresName,CouresTime,Notes from mstanford.dbo.Tb_Student_Coures--查看所有資料完整寫
select distinct studentno from mstanford.dbo.Tb_Student_Coures--distinct查看資料并且去掉重復
select StudentNo as 學號,SCNo as 編號,CouresName as 課程名稱,CouresTime as 課程時間,Notes as 備注 from mstanford.dbo.Tb_Student_Coures--查詢使用別名


------------------------排序查詢 ORDER BY
update Tb_Student_Coures set CouresTime='2008-01-02' where SCNo='43' --更改
select * from Tb_Student_Coures order by CouresTime DESC --查詢所有某列降序
select * from Tb_Student_Coures order by StudentNo desc,CouresTime desc --查詢所有多列降序

------------------------查詢限定行 TOP N PERCENT
select top 3 * from Tb_Student_Coures --查詢表中前3行
select top 1 percent * from Tb_Student_Coures --查詢表中1%行(percent百分比)
select top 50 percent * from Tb_Student order by StudentNo desc,Tuition asc --查詢表中1%行(percent百分比)StudentNo 降序,Tuition 降序

------------------------條件查詢 WHERE --邏輯運算子 'NOT' 'AND' 'OR' 'IS NULL'回傳TRUE 'IS NOT NULL'回傳FALSE
select * from mstanford.dbo.Tb_Student_Coures where Notes='通過' -------------單條件查詢(使用比較運算子)
select * from mstanford.dbo.Tb_Student_Coures where SCNo>=40 -------------單條件查詢(使用比較運算子)
select * from mstanford.dbo.Tb_Student_Coures where SCNo>40 AND notes='通過' -------------多條件查詢(使用邏輯運算子)
select * from mstanford.dbo.Tb_Student_Coures where Notes is NULL -------------查詢表中 Notes值NULL空的行
select * from mstanford.dbo.Tb_Student_Coures where Notes is not null -------------查詢表中 Notes值為NOT NULL的行

select * from mstanford.dbo.Tb_Student_Coures where Notes != '通過' -------------查詢表中 notes值不是'通過'的行(不檢查值為NULL)的行
select * from mstanford.dbo.Tb_Student_Coures where not Notes = '通過' -------------查詢表中 notes值不是'通過'的行(不檢查值為NULL)的行

select * from mstanford.dbo.Tb_Student_Coures where (StudentNo='200709002' or StudentNo='200709003') and CouresName='.net' -------------理解運算優先級ADN > OR,()限制優先級

------------------------SQL Server內置函式,可以與INSERT UPTATE DELETE等一起使用:1.字串函式,2.日期函式,3.數字函式,4.系統函式

select STUFF(PName,1,0,'拳皇_') as 名稱,WeaponID,SkillID from DB_King_Fighters.dbo.player --使用stuff洗掉并且插入字符
select upper(CouresName) as 課程名稱 from mstanford.dbo.Tb_Student_Coures ------------- 查詢表中課程名稱,并將小寫轉換成大寫
select * from mstanford.dbo.Tb_Student_Coures where len(CouresName)>3 -------------查詢表中課程名稱大于3的選課資訊
select * from mstanford.dbo.Tb_Student_Coures where CouresTime<GETDATE() -------------查詢選課日期再當前日期之前的選課資訊
select * from mstanford.dbo.Tb_Student_Coures where DATENAME(DW,CouresTime)='星期三' -------------查詢選課為星期三的選課資訊

select CONVERT(int,SUBSTRING(StudentNo,1,2))+CONVERT(int,SUBSTRING(StudentNo,3,2)) as 學號 from mstanford.dbo.Tb_Student_Coures -------------理解substring,convert

--CONVERT(int,SUBSTRING(StudentNo,1,2))--SUBSTRING(實體,截取開始位,截取結束位)
select * from mstanford.dbo.Tb_Student_Coures
update mstanford.dbo.Tb_Student_Coures set CouresTime='2009-09-09',CouresName='jsp',StudentNo='200709004' where SCNo=43
delete from mstanford.dbo.Tb_Student_Coures where SCNo=39--理解洗掉表中某一行
select top 2 StudentNo,Notes from mstanford.dbo.Tb_Student_Coures where Notes='通過' order by StudentNo desc--理解查表行數,查表列數,查表條件,查表排序一起運用
select * from mstanford.dbo.Tb_Student_Coures where SUBSTRING(CouresName,1,1)='j' and Notes is not null--理解is not null的用法,不能使用!= null

------------------------------------------------------------LIKE 運算子
------------------------------------------------------------通配符 % 任意0個或者多個字符
select ProductName,UnitPrice from Products where ProductName like 'c%'--通配符%表示任意字符的匹配(以C開頭)
select ProductName,UnitPrice from Products where ProductName like '%t'--(以T結尾的)
select ProductName,UnitPrice from Products where ProductName like 'c%t'--(以c開頭以t結尾)
select ProductName,UnitPrice from Products where ProductName like '%t%'--(包含t)
------------------------------------------------------------通配符 _ 任意單個字符
select ProductName,UnitPrice from Products where ProductName like 't_fu'
select ProductName,UnitPrice from Products where ProductName like '_____'--產品名稱長度是5個字符的產品

select ProductName,UnitPrice from Products where ProductName like '_e%'--查詢第二個位元組為e的產品名稱
select ProductName,UnitPrice from Products where ProductName like '_a%' and QuantityPerUnit like '%pkgs%'
------------------------------------------------------------通配符 [] 指定一系列的字符,只要滿足這些字符其中之一且出現在[]通配符的位置的字串就滿住查詢條件
select ProductName from Products where ProductName like '%[_]%'--名稱中帶有_的資料
update Products set ProductName='abc_123' where ProductName='huwei_520' --更改資料
select ProductName,UnitPrice from Products where ProductName like '%[abfg]'--名稱最后一位是[abfg]的資料


------------------------------------------------------------IN 運算子(相對于or,IN簡捷,后面可以是SQL陳述句)
select ProductName,SupplierID from Products where SupplierID=1 or SupplierID=4 or SupplierID=3
select ProductName,SupplierID from Products where SupplierID in(1,3,4) --同上兩句相等


------------------------------------------------------------BETWEEN 運算子
select ProductName,UnitPrice from Products where UnitPrice between 6 and 10 order by UnitPrice desc--unitprices價格在6-10之間的產品名稱和單價資料,unitprices按降序排列,排序規則放在陳述句最后
select LAStName,BirthDate from Employees where BirthDate between '1952-01-01' and '1960-01-01'--查詢出生區間出生日期between

------------------------------------------------------------聚合函式 SUM MAX MIN AVG COUNT
--DATE type 求min/max按照時間的先后排列的,日期越早月小,
--CHAR type 求min/max按照搜首字母A-Z的順序排列,越后越大
--漢字 type 求min/max按照全拼拼音進行比較,若首字母形同則比下一個字符
------------------------------------------------------------SUM聚合函式
select top 10 SUM(UnitPrice) AS 前十價格之和 from Products--前十價格之和
select * from Products
select SUM(UnitPrice*Quantity) AS 所有商品價格和 from [Order Details] where OrderID='10249'--OrderID是10249所有商品價格的和

------------------------------------------------------------MAX/MIN函式
select MAX(UnitPrice) AS 最高價格產品 from Products--最高價格產品
select MIN(BirthDate) AS 年紀最大員工 from Employees--年齡最大的員工生日
------------------------------------------------------------AVG集函式
select AVG(UnitPrice) AS 商品價格平均價 from Products
------------------------------------------------------------COUNT函式
select COUNT(ProductName) AS 商品個數 from Products--商品個數
select COUNT(*) AS 記錄數 from Products--查詢所有記錄數(包括空值)

------------------------------------------------------------多聚合函式一起用
select COUNT(*) AS 總記錄數,AVG(UnitPrice) AS 平均價格, MAX(UnitPrice)AS 最高價格 from Products--多聚合函式的使用

------------------------------------------------------------分組查詢
------------------------------------------------------------GROUP BY字句
分組查詢語法: SELECT 分組列, 聚合列 FROM 表名 WHERE 普通列 GROUP BY 分組列 HAVING 分組列, 聚合列 ORDER BY 分組列, 聚合列
select EmployeeID,MIN(OrderDate) AS 每個員工最早訂單時間 from Orders group by EmployeeID order by EmployeeID ASc--聚合函式與分組查詢共用
------------------------------------------------------------HAVING字句
select EmployeeID,COUNT(*) AS 訂單數量 from Orders group by EmployeeID having COUNT(*)>100
select EmployeeID,COUNT(*) AS 訂單數量 from Orders group by EmployeeID having COUNT(*)>100 and EmployeeID>2--和下一句對比,如果不是判斷結果集,那么可以用下面的寫法
select EmployeeID,COUNT(*) AS 訂單數量 from Orders where EmployeeID>2 group by EmployeeID having COUNT(*)>100
select * from Orders

------------------------------------------------------------作業1
select FirstName,LAStName,HomePhone from Employees where HomePhone like '(%)_5%122' --%_用法
select count(ProductName) AS 商品數, avg(unitprice) AS 平均價格,SUM(unitprice) AS 單價和, max(unitprice) AS 最高價, min(unitprice) AS 最低價 from Products--聚合函式使用
select ProductID AS 產品編號, MAX(UnitPrice*Quantity) AS 訂單額 from [Order Details] where ProductID>70 and OrderID>11020 GROUP BY ProductID order by MAX(UnitPrice*Quantity) desc--聚合函式 group by的使用

------------------------------------------------------------上機 1模糊查詢
select ProductName,UnitPrice from Products where ProductName like 'c_[a-f][^g-z]%'
select * from Products
UPDATE Products set ProductName='[楊磊牛逼]' where ProductID=1
select ProductName,UnitPrice from Products where ProductName like '%[%]%'--包含%的產品名稱和單價
select ProductName from Products where ProductName like '%[_]%'
select ProductName from Products where ProductName like '%[[]%]%'

select * from Employees where (City='london' or City='kirkland' or City='seattle') and HomePhone like '%2'--和下面的一樣
select * from Employees where City in ('london','kirkland','seattle') and HomePhone like '%2'

------------------------------------------------------------2聚合函式
select AVG(datediff(YY,BirthDate,GETDATE())) AS 平均年紀,
MAX(datediff(YY,BirthDate,GETDATE())) AS 最大年紀
from Employees

select COUNT(*) AS 記錄次數,COUNT(Region) AS Region欄位值的個數 from Employees--計算記錄次數和Region not is null 的次數
select * from Orders
select CustomerID,OrderID from Orders where OrderID>11011 and EmployeeID>2
select CustomerID,COUNT(*) as 訂單數量 from Orders where OrderID>11011 group by CustomerID having COUNT(*)>2

select * from Customers
select Country as 國家,COUNT(CustomerID) as 客戶數量 from Customers group by Country
select Country as 國家,COUNT(CustomerID) as 客戶數量,CompanyName as 公司名稱名稱 from Customers where CompanyName like 'b%' group by Country,CompanyName
select Country as 國家,COUNT(CustomerID) as 客戶數量,CompanyName as 客戶公司名稱,Country as 國家 from Customers
where CompanyName like 'b%' and LEN(Country) between 5 and 10 group by Country,CompanyName,Country --理解集合函式,between運算子group by的用法

------------------------------------------------------------表的基本連接
------------------------------------------------------------兩表連接
use Northwind
--查詢屬于beverages和condiments類的商品名,切商品名以'c'開頭
select Categories.CategoryID,Categories.CategoryName,--種類ID,種類名稱
Products.CategoryID,Products.ProductName--商品.種類ID,商品.商品名稱
from Categories,Products
where Categories.CategoryID=Products.CategoryID--兩張表的連接條件
and CategoryName in('beverages','condiments')--查詢類別(查詢這兩個種類)
and ProductName like 'c%'

--select TB_A.A,TB_B.C FROM TB_A,TB_B WHERE TB_A.C=TB_B.C
select * from Categories
select * from Products
select * from [Order Details]

--TB_A 表和 --TB_B都存在欄位C,所以在select陳述句中使用該欄位時,一定要知名其所在的表,如TB_A.C、TB_B.C,其他的充滿欄位要需要進行同樣的處理,否則資料庫系統會報錯
--使用sel server關鍵字作為表名,列名的時候,需要使用“[]”包括起來,例如create table [order]
--select陳述句首先執行from字句,由于定義表別名是在from字句中執行,而在其他子句中使用,所以在select陳述句的任何子句中都可以使用表的別名
select c.CategoryID,c.CategoryName,
p.CategoryID,p.ProductName,
o.OrderID
from Categories as c,Products as p,[Order Details] as o
where c.CategoryID=c.CategoryID
and p.ProductID=o.ProductID
and CategoryName in('beverage','condiments')
and ProductName like 'c%'
and o.OrderID>1060

------------------------------------------------------------內連接
--內連接也稱為等同連接,回傳的結果是兩個表中所有相匹配的資料,舍棄不匹配的資料
select * from Products
select * from Categories
select Categories.CategoryID as 種類ID,Categories.CategoryName as 種類名稱,
Products.CategoryID as 種類ID,Products.ProductName as 種類名稱
from Categories join Products
on Categories.CategoryID=Products.CategoryID
where CategoryName in('beverages','condiments')
and ProductName like 'c%'

select * from Customers
select * from Orders

select kh.CompanyName as 客戶公司,kh.ContactName as 客戶名字,kh.Phone as 客戶電話,dd.OrderID as 訂單編號,dd.OrderDate as 訂單日期
from Customers as kh,Orders as dd
where kh.CustomerID=dd.CustomerID
order by 訂單編號

select kh.CompanyName as 客戶公司,kh.ContactName as 客戶名字,kh.Phone as 客戶電話,dd.OrderID as 訂單編號,dd.OrderDate as 訂單日期
from Customers as kh left join Orders as dd
on kh.CustomerID=dd.CustomerID
order by 訂單編號

------------------------------------------------------------外連接
select * from Customers
select * from Employees
select kh.City as 客戶所在城市,yg.FirstName+yg.LastName as 員工姓名,kh.ContactName as 客戶姓名
from Employees as yg right join Customers as kh
on kh.City=yg.City


--全外部鏈接full on...on
select * from Customers
select * from Orders
select Orders.OrderID 訂單編號,Orders.OrderDate 訂單日期,Customers.CompanyName 客戶公司
from Customers full join Orders
on Customers.CustomerID=Orders.CustomerID

-----------------------------------------------------------SQL SERVER執行順序

--SELECT...
--FROM...
--WHERE...
--GROUP BY...
--HAVING...
--ORDER BY...


--查詢供貨商的公司名稱和所供應的商品名稱
select * from Suppliers
select * from Products
select * from [Order Details]
select s.CompanyName,p.ProductName
from Suppliers s,Products p
where s.SupplierID=p.SupplierID

select s.CompanyName,p.ProductName
from Suppliers s join Products p
on s.SupplierID=p.SupplierID

select s.CompanyName,p.ProductName,o.OrderID
from Suppliers s,Products p,[Order Details] o
where s.SupplierID=p.ProductID and p.ProductID=o.ProductID

select Suppliers.CompanyName,Products.ProductName,[Order Details].OrderID
from Suppliers join Products on Suppliers.SupplierID = Products.SupplierID join [Order Details] on Products.ProductID = [Order Details].ProductID

select * from Customers
select * from Suppliers
select c.CompanyName 客戶姓名,c.[Address] 客戶地址,s.CompanyName 供貨商公司,s.ContactName 供貨商聯系人
from Customers c left join Suppliers s
on c.City=s.City

select * from Orders
select * from Employees
select * from Customers
select Orders.OrderID as 訂單編號,Employees.FirstName+Employees.LastName as 負責人姓名,Customers.CompanyName as 下訂單公司名稱
from Employees right join Orders on Orders.EmployeeID=Employees.EmployeeID left join Customers on Orders.CustomerID=Customers.CustomerID



---------------------------------------------------------------------------第二階段
1、資料庫設計階段
需求分析:收集資訊
概念設計:標識物體、標識屬性、標識關系-》E-R圖[物體(Entity)關系(Relationship)圖] 軟體vision
邏輯設計:E-R圖轉換成相應的表并通過3大范式進行審核
物理設計:選擇合適物理實作
實施:
運行和維護:

范式(Normal Formate)NF
第一范式 確保每一列的原子性,不可再拆分
第二范式 除了主鍵外,所有的列都依賴于主鍵,并且沒有一個物體是組合主鍵
不符合第二范式會有問題
1資料冗余
2跟新例外
3插入例外
4洗掉例外
第三范式 非關鍵字對非主鍵的間接函式依賴


ER模型 E-R模型圖 物體(Entity)關系(Relationship)圖 vision
PowerDesigner 概念資料模型
PhysicalDiagram 物理圖

物體:物體是現實生活中區別于其他事物,具有自己屬性的物件,同一類物體的所有實體就是構成該物件的物體集,
屬性:屬性是物體的特征
關系:物體之間存在的聯系


關系分類
1對1關聯 1:1屬于
班級 輔導員
一個班級只有一個輔導員
一個輔導員只負責一個班級
1對多關聯 1:N擁有
班級 學生
一個班級有多個學生
多個學生屬于一個班級
多對1關聯 N:1

辦事處與員工之間是一對多的關系,反之員工與辦事處之間就是多對一的映射基礎

多對多關聯 N:M
學生 教師
一個學生有多名老師(語文數學)
一個老師教多名學生


部門中擁有很多員工(1:N)
一個員工可以管理一個部門(1:1)
辦事處中擁有很多員工(1:N)
員工可以存在很多技能(M:N)

映射基數:
1:1(員工管理部門)
1:N(部門擁有員工)
N:1(員工屬于部門)
M:N(員工和技能)

--------------------------------------------------------------------------------------------------
變數 運算子 批處理陳述句 流程控制陳述句

全域變數
@@ERROR 回傳執行的上一個陳述句的錯誤號
@@IDENTITY 回傳最后插入的標識值
@@ROWCOUNT 回傳受上一陳述句影響的行數
@@SERVERNAME 回傳運行 SQL Server 的本地服務器的名稱
@@MAX_CONNECTIONS 回傳允許同時進行的最大用戶連接數

print @@version

區域變數:由用戶定義的變數,其作用域在定義它的代碼塊中(指存盤程序,函式,匿名的T—SQL代碼塊),一般是在兩個GO之間
區域變數:以@開頭,由用戶定義,先宣告再賦值最后使用

宣告:
declare @變數名 資料型別
宣告并賦值:
declare @變數名 資料型別=值

給變數賦值:
set @變數名 = 值
select @變數名 = 值
select @變數名 = 列名 from 表

使用變數:
列印變數:
print @變數名
select @變數名
select @變數名 as 別名

set 將已經確定的常量賦值給區域變數
select 將從資料庫中查詢的結果賦值給區域變數

go陳述句的作用:
go前面的陳述句執行完之后,才會執行其后的代碼
作為批處理陳述句的結束,go之前宣告的變數,在go之后不能使用

--------------------------------------------------------------------------------使用T-SQL編程
create database Company_DB
on(
name='Company_DB',
filename='E:\MySQLServerDatabase\Company_DB.mdf'

)
log on(
name='Company_DB_log',
filename='E:\MySQLServerDatabase\Company_DB.ldf'
)
create table Office
(
OfficeCode nvarchar(20) primary key,--辦公司代號
OfficeAddress nvarchar(100) not null unique--辦公司地址
)
create table Department
(
DeptNo nvarchar(20) primary key, --部門代號
DeptName nvarchar(20) not null unique,--部門名稱
Principal nvarchar(20) --部門負責人
)
create table Employee
(
EmpNo nvarchar(20) primary key,--員工號
EmpName nvarchar(20) not null,--員工名字
EmpAddress nvarchar(100) not null,--員工地址
EmpPhone varchar(12) not null,--員工電話
Birthday datetime not null,--員工生日
HireDate datetime not null,--入職時間
DeptNo nvarchar(20) foreign key references Department(DeptNo),--外鍵
OfficeCode nvarchar(20) foreign key references Office(OfficeCode)--外鍵
)

insert into Office
values ('C01','中山北路200號')
insert into Office
values ('C02','北京中路35號')
insert into Office
values ('C03','福州路10號')

insert into Department(DeptNo,DeptName)
values ('D01','技術部')
insert into Department(DeptNo,DeptName)
values ('D02','市場部')
insert into Department(DeptNo,DeptName)
values ('D03','行政部')

insert into Employee
values ('E001','Tom','凱撒大廈501','021-45364743','1980-10-02','2004-04-06','D01','C01')
insert into Employee
values ('E002','Jack','凱撒大廈502','021-45364743','1980-01-03','2004-05-16','D01','C01')
insert into Employee
values ('E003','White','凱撒大廈503','021-45364743','1980-01-04','2003-05-06','D02','C01')
insert into Employee
values ('E004','Smith','凱撒大廈504','021-45364743','1980-05-02','2000-05-22','D02','C02')
insert into Employee
values ('E005','John','凱撒大廈505','021-45364743','1980-06-01','2004-02-13','D02','C02')
insert into Employee
values ('E006','Slider','凱撒大廈506','021-45364743','1982-08-02','2005-03-12','D03','C02')
insert into Employee
values ('E007','Buth','凱撒大廈507','021-45364743','1983-02-12','2006-05-06','D03','C02')
insert into Employee
values ('E008','Jennifer','凱撒大廈508','021-45364743','1980-11-02','2004-05-16','D01','C03')
insert into Employee
values ('E009','Kelly','凱撒大廈509','021-45364743','1980-01-23','2004-05-22','D01','C03')
insert into Employee
values ('E010','Winston','凱撒大廈510','021-45364743','1978-10-02','2002-09-06','D01','C03')
insert into Employee
values ('E011','Joy','凱撒大廈511','021-45364743','1980-11-12','2004-12-06','D01','C03')

drop table Office
drop table Department
drop table Employee

select * from Office
select * from Department
select * from Employee

use Company_DB

declare @DeptNo nvarchar(10)='D01'--宣告變數并賦值
select @DeptNo

declare @EmpNo nvarchar(10)='胡偉'--宣告變數
print @EmpNo

--------------------------------------------------------------------------------
use Company_DB
go
--查詢Dept='D10'的員工號
declare @DeptNo nvarchar(10)='D01'
select EmpNo from Employee where DeptNo=@DeptNo

--把查詢的EmpNo的查詢結果最后一條記錄值賦值給區域變數@EmpNo
declare @EmpNo nvarchar(10) --定義變數
declare @DeptNo nvarchar(10)='D01'--定義點亮并且賦值
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo
select @EmpNo

--------------------------------------------------------------------------------
--找出一部門中工齡最大的員工(按照工齡升序排列,自動取最后一條資料賦值)
declare @EmpNo nvarchar(10)
declare @DeptNo nvarchar(10)='D01'
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo group by EmpNo order by MAX(DATEDIFF(yyyy,hiredate,getdate())) asc
print @EmpNo--輸出顯示

--更新部門負責人 E010 'D01'
update Department set principal = @EmpNo where DeptNo = @DeptNo


--找出二部門中工齡最大的員工(按照工齡升序,自動取最后一條資料賦值)
set @DeptNo='D02'--為變數@DeptNo重新復制
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo group by EmpNo order by MAX(DATEDIFF(yyyy,hiredate,getdate()))
print @EmpNo
update Department set Principal=@EmpNo where DeptNo=@DeptNo

--找出三部門中工齡最大的員工(按照工齡升序,自動取最后一條資料賦值)

set @DeptNo='D03'
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo group by EmpNo order by MAX(DATEDIFF(yyyy,hiredate,getdate()))
print @EmpNo
update Department set Principal=@EmpNo where DeptNo=@DeptNo

go
select * from Department
go

print '錯誤號碼'+convert(nvarchar(225),@@error
select @@VERSION as '版本代號'

------------------------------------------------運算子-----------------------------------
declare @OptNumber int=12436
--print '轉換之前'+@OptNumber 失敗int要想和varchar格式一起列印需要把int轉換成varchar
print '轉換前:'+convert(varchar(5),@optNumber)
declare @reverse varchar(5)
--取除個位數
declare @unit int = @OptNumber%10--6
set @reverse=(CONVERT(varchar(1),@unit))--6賦值給倒序變數,賦值順序左→右
print '逆序number:'+@reverse
--去掉個位數,變數OptNumber將變成1243
set @OptNumber=@OptNumber/10--1243
set @unit=@OptNumber%10--3
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse
set @OptNumber=@OptNumber/10--124
set @unit=@OptNumber%10--4
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse
set @OptNumber=@OptNumber/10--12
set @unit=@OptNumber%10--2
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse
set @OptNumber=@OptNumber/10--1
set @unit=@OptNumber%10--1
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse

-----------------求1,2,3........100之間的奇數和
declare @tableNum table(Num int)--雖然求奇數不需要table型別變數,但是為了演示位運算子,所以定義table型別變數以便查詢
declare @loop int =1
while @loop<=100--回圈次數
begin
insert into @tableNum values(@loop)
set @loop=@loop+1
end
select SUM(num) from @tableNum where Num & 1=1
-----練習
declare @table table(num int)
declare @i int =1
while @i<=100
begin
insert into @table values (@i)
set @i=@i+1
end
select sum(num) from @table where num % 2=1
------------------------------ALL關鍵字----------------------
--ALL:將特定值與查詢的結果集中所有的資料進行比較,若結果集中資料都滿足該條件則回傳結果為true,否則結果為false
--語法:
--特定值 比較運算子 ALL(查詢陳述句)
create table Expertise(
SKillName nvarchar(20),
SKillLevel int,
EmpNo nvarchar(20)
)
insert into Expertise values('C','2','E010')
insert into Expertise values('C','1','E03')
insert into Expertise values('C','2','E02')
insert into Expertise values('C','3','E008')
insert into Expertise values('C','2','E005')
insert into Expertise values('C#','4','E006')
insert into Expertise values('C#','3','E007')
insert into Expertise values('DELPHI','1','E009')
insert into Expertise values('JAVA','2','E004')
SELECT * FROM Expertise

IF 2<=ALL(SELECT SKillLevel FROM Expertise)
PRINT '全部員工技能都通過了2級'
ELSE
PRINT '有員工技能不達標,還需要培訓'


-------------------------------ANY關鍵字---------------------
--ANY:將特定值與查詢的結果集中所有的資料進行比較,若結果集中任意一個資料滿足該條件則回傳結果為true,否則結果為false
--語法:
--特定值 比較運算子 ANY(查詢陳述句)
select * from Expertise
--if 0<=ANY(SELECT SKillLevel FROM Expertise)
if 2<=ANY(SELECT SKillLevel FROM Expertise where EmpNo='E010')
PRINT '已經有員工技能超過了2級'
ELSE
PRINT '全部員工的技能不達標,需要加強練習'

-------------------------------EXISTS關鍵字---------------------
--Exists:判斷查詢的結果集中是否存在資料,若存在資料,則結果為true,否則結果為false
--注意:可以使用not exists
select * from Employee
if Exists (SELECT * FROM Employee WHERE EMPADDRESS IS NULL)
PRINT '有員工沒有填寫住址'
ELSE
PRINT '全部都填寫住址了'
----------------------------------------------------SQL流程控制陳述句-------------
--BEGIN-END
--作用:相當于JAVA,C#中{}
--注意
--當陳述句塊中陳述句多于一句時,需要使用begin-end
--degin-end之間必須只有存在一條陳述句
create table Salary(
Id int identity(1,1) primary key,
EmpNo NVARCHAR(20) FOREIGN KEY references Employee(EmpNo),
Salary money,
StartTime datetime
)
select * from Salary
select * from Expertise
select * from Office
select * from Department
select * from Employee

insert into Salary values ('E001','5000','2004-04-06 00:00:00')
insert into Salary values ('E002','6500','2004-05-16 00:00:00')
insert into Salary values ('E003','5500','2003-05-06 00:00:00')
insert into Salary values ('E004','7200','2000-05-22 00:00:00')
insert into Salary values ('E005','5000','2004-02-13 00:00:00')
insert into Salary values ('E006','8000','2005-03-12 00:00:00')
insert into Salary values ('E007','11000','2006-05-06 00:00:00')
insert into Salary values ('E008','4800','2004-05-16 00:00:00')
insert into Salary values ('E009','6700','2004-05-22 00:00:00')
insert into Salary values ('E010','8000','2002-09-06 00:00:00')
insert into Salary values ('E011','9500','2004-12-06 00:00:00')

--如果某個員工的技能等級已經達到4級以上且最高,給這個員工增加基本工資500
declare @emp nvarchar(10)
declare @level int
declare @salary money
--查詢最高技能等級的員工
select @emp=EmpNo from Expertise order by SKillLevel
print @emp--E006
select @level=MAX(SKillLevel) from Expertise
print @level--4
if @level>=4
begin
select @salary=Salary from Salary where EmpNo=@emp
insert into Salary values (@emp,@salary+500,GETDATE())
end
GO

-------------------------------------IF ELSE 條件陳述句-------------------------------------
/**
if-else
作用:進行條件判斷
作業原理:條件成立執行if陳述句塊,不成立else陳述句塊
注意:
else子句可以省略
在if,else子句均可以嵌套if-else結構
*/
declare @worktime int
declare @emp nvarchar(10)
declare @salary money
select @emp=EmpNo,@worktime=DATEDIFF(YYYY,hireDate,GETDATE()) from Employee order by DATEDIFF(YYYY,hireDate,GETDATE()) asc
print @emp
if @worktime>=4
begin
select @salary=Salary from Salary where EmpNo=@emp
insert into Salary values (@emp,@salary+1000,GETDATE())
end
select * from Salary

-------------------------------------WHILE 陳述句-------------------------------------
/*
while
作用:進行回圈
作業原理:先判斷后執行
**/
select * from Expertise

declare @count int
while(1=1)--無限回圈
begin
select @count=COUNT(*) from Expertise where SKillName like '%c%' and SKillLevel<3
if(@count>0)
begin
update Expertise set SKillLevel+=1 where SKillName like '%c%' and SKillLevel<3
end
else
break--沒有員工C語言技能低于3級后就退出回圈
end
----------------------------------CASE 分支陳述句--------------------------------------------------
/*
case-end
作用:類似多重條件結構,用于進行多路分支
case 欄位名
when 值1 then 回傳值1
when 值2 then 回傳值2
...
else 回傳值n
end
作業原理:將欄位的值逐一與when陳述句之后的值進行匹配,若存在匹配項,則回傳then之后值,若不存在匹配項,則回傳else之后回傳值,其中else子句可以省略
case
when 條件1 then 回傳值1
when 條件2 then 回傳值2
...
else 回傳值n
end
作業原理:將逐一判斷when陳述句之后的條件,若條件為真,則回傳then之后值,若條件為假,則回傳else之后回傳值,其中else子句可以省略
*/
create table TimeWork(
Id int identity(1,1) primary key,
EmpNo nvarchar(10),
WorkState nvarchar(20),
WorkDate datetime
)
go
--創建表
insert into TimeWork values ('E001','病假','2008-10-11')
insert into TimeWork values ('E001','調休','2008-10-10')
insert into TimeWork values ('E001','正常上班','2008-10-08')
insert into TimeWork values ('E001','正常上班','2008-10-09')
insert into TimeWork values ('E001','正常上班','2008-10-12')
insert into TimeWork values ('E002','加班','2008-10-11')
insert into TimeWork values ('E002','休年假','2008-10-08')
insert into TimeWork values ('E002','休年假','2008-10-09')
insert into TimeWork values ('E002','正常上班','2008-10-10')
insert into TimeWork values ('E003','病假','2008-10-08')
insert into TimeWork values ('E003','正常上班','2008-10-09')
insert into TimeWork values ('E003','正常上班','2008-10-10')
insert into TimeWork values ('E003','正常上班','2008-10-11')
insert into TimeWork values ('E004','請假','2008-10-11')
insert into TimeWork values ('E004','休息','2008-10-08')
insert into TimeWork values ('E004','正常上班','2008-10-09')
insert into TimeWork values ('E004','正常上班','2008-10-10')
insert into TimeWork values ('E005','調休','2008-10-10')
insert into TimeWork values ('E005','正常上班','2008-10-08')
insert into TimeWork values ('E005','正常上班','2008-10-09')
insert into TimeWork values ('E005','正常上班','2008-10-11')
go
select * from TimeWork
drop table TimeWork

select WorkDate as 日期,
COUNT(case WorkState when '病假' then '0' end) as 病假,
COUNT(case WorkState when '調休' then '0' end) as 調休,
COUNT(case WorkState when '請假' then '0' end) as 請假,
COUNT(case WorkState when '正常上班' then '0' end) as 正常上班,
COUNT(case WorkState when '加班' then '0' end) as 加班,
COUNT(case WorkState when '休年假' then '0' end) as 休年假,
COUNT(case WorkState when '休息' then '0' end) as 休息,
COUNT(case WorkState when '其他' then '0' end) as 其他
from TimeWork group by WorkDate order by WorkDate desc

select * from TimeWork

select WorkDate,
病假=sum(case workstate when '病假' then 1 else 0 end),
調休=sum(case workstate when '調休' then 1 else 0 end),
請假=sum(case workstate when '請假' then 1 else 0 end),
正常上班=sum(case workstate when '正常上班' then 1 else 0 end),
加班=sum(case workstate when '加班' then 1 else 0 end),
休年假=sum(case workstate when '休年假' then 1 else 0 end),
其他=sum(case workstate when '其他' then 1 else 0 end)
from TimeWork
group by workdate
order by workdate desc
----------------------------------RETURN 陳述句--------------------------------------------------
/*
break:跳出回圈結構
return:跳出當前的批處理,而進入下一個批處理的執行
goto:必須和label一起配合使用,跳轉到相應label標簽處
*/

declare @num int=0
while(1=1)
begin
set @num+=1
if(@num>10)
RETURN
PRINT @num
end
go
select @@CONNECTIONS as '連接數量'
go

----------------------------------GOTO 陳述句--------------------------------------------------
SELECT * FROM Expertise
declare @num1 int
declare @num2 int
LABEL1:
PRINT '最高的技能級別就是6級了,不能再升級了'
WHILE(0=0)
BEGIN
SELECT @num1 =COUNT(*) FROM Expertise WHERE SKillLevel<2
IF(@num1>0)
BEGIN
UPDATE Expertise SET SKillLevel=SKillLevel+1
SELECT @num2=COUNT(*) FROM Expertise WHERE SKillLevel>6--查看Expertise表中SKillLevel列有幾行大于6的資料并且把這個資料賦值給@num2
IF(@num2>0)--如果@num2>0,
BEGIN
GOTO LABEL1--跳轉到錨點LABEL1執行
END
END
END

PRINT @@IDENTITY

--------------------------------------課后操作題-----------------------------------------------
create table orders
(
OrdersID nvarchar(100),
ProductID nvarchar(100),
[Date] datetime,
Number int,
[Money] int
)

insert into orders values ('SD-90102001','HW03202','1990-10-20 03:20:00','5','340')
insert into orders values ('SD-90112001','HW03212','1990-11-12 10:22:00','10','1880')
insert into orders values ('SD-90112001','HW03205','1990-11-24 12:25:35','30','2400')
insert into orders values ('SD-90102001','HW03211','1990-10-12 05:06:23','20','500')
insert into orders values ('SD-90102002','HW03211','1990-10-15 06:38:36','10','250')
insert into orders values ('SD-90082002','HW03212','1990-08-24 11:39:09','5','950')
insert into orders values ('SD-90082003','HW03202','1990-08-26 10:21:17','5','340')
insert into orders values ('SD-90052003','HW03223','1990-05-01 11:45:18','10','240')
insert into orders values ('SD-90062003','HW03224','1990-06-01 05:40:54','20','5000')
insert into orders values ('SD-90102003','HW03223','1990-10-17 06:26:25','5','350')
insert into orders values ('SD-90012005','HW03212','1990-01-08 07:28:22','7','1300')
insert into orders values ('SD-90022005','HW03223','1990-02-02 08:05:02','10','700')
insert into orders values ('SD-90012005','HW03202','1990-01-07 11:11:08','5','340')
insert into orders values ('SD-90062005','HW03202','1990-06-22 12:17:30','5','340')

drop table orders
SELECT * FROM orders
-------------一下兩張表union all的表
select
商品編號=ProductID,銷售詳情='銷售數量',
[1月]=sum(case datepart(month,[Date])
when 1 then Number
else 0
end),
[2月]=sum(case datepart(month,[Date])
when 2 then Number
else 0
end),
[3月]=sum(case datepart(month,[Date])
when 3 then Number
else 0
end),
[4月]=sum(case datepart(month,[Date])
when 4 then Number
else 0
end),
[5月]=sum(case datepart(month,[Date])
when 5 then Number
else 0
end),
[6月]=sum(case datepart(month,[Date])
when 6 then Number
else 0
end),
[7月]=sum(case
when datepart(month,[Date])=7 then Number
else 0
end),
[8月]=sum(case
when datepart(month,[Date])=8 then Number
else 0
end),
[9月]=sum(case
when datepart(month,[Date])=9 then Number
else 0
end),
[10月]=sum(case
when datepart(month,[Date])=10 then Number
else 0
end),
[11月]=sum(case
when datepart(month,[Date])=11 then Number
else 0
end),
[12月]=sum(case
when datepart(month,[Date])=12 then Number
else 0
end)
from orders
group by ProductID
union all
select
商品編號=ProductID,銷售金額='銷售金額',
[1月]=sum(case datepart(month,[Date])
when 1 then [money]
else 0
end),
[2月]=sum(case datepart(month,[Date])
when 2 then [money]
else 0
end),
[3月]=sum(case datepart(month,[Date])
when 3 then [money]
else 0
end),
[4月]=sum(case datepart(month,[Date])
when 4 then [money]
else 0
end),
[5月]=sum(case datepart(month,[Date])
when 5 then [money]
else 0
end),
[6月]=sum(case datepart(month,[Date])
when 6 then [money]
else 0
end),
[7月]=sum(case
when datepart(month,[Date])=7 then [money]
else 0
end),
[8月]=sum(case
when datepart(month,[Date])=8 then [money]
else 0
end),
[9月]=sum(case
when datepart(month,[Date])=9 then [money]
else 0
end),
[10月]=sum(case
when datepart(month,[Date])=10 then [money]
else 0
end),
[11月]=sum(case
when datepart(month,[Date])=11 then [money]
else 0
end),
[12月]=sum(case
when datepart(month,[Date])=12 then [money]
else 0
end)
from orders
group by ProductID

----------------一下答案,參考上面容易理解c
select
商品編號=ProductID,
[1月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 1 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 1 then [money]
else 0
end)),
[2月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 2 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 2 then [money]
else 0
end)),
[3月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 3 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 3 then [money]
else 0
end)),
[4月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 4 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 4 then [money]
else 0
end)),
[5月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 5 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 5 then [money]
else 0
end)),
[6月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 6 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 6 then [money]
else 0
end)),
[7月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 7 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 7 then [money]
else 0
end)),
[8月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 8 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 8 then [money]
else 0
end)),
[9月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 9 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 9 then [money]
else 0
end)),
[10月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 10 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 10then [money]
else 0
end)),
[11月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 11 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 11 then [money]
else 0
end)),
[12月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 12 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 12 then [money]
else 0
end))
from orders
group by ProductID


--查看某個時間的月份
select datepart(month,[Date]) from orders where [date]='1990-10-20 03:20:00'

--上機階段1
---------------------------變數的定義和使用
/*
用戶狀態:待審核,已審核,被屏蔽
用戶角色:待審核會員,普通會員,VIP會員,超級管理員
用戶在剛注冊時狀態為待審核,角色是待審核會員,管理員進行確認和管理
*/
create table UserState(
Id int identity(1,1) primary key,
[State] nvarchar(100)
)
create table RoleInf(
Id int identity(1,1) primary key,
Rolename nvarchar(100),
Roledesc nvarchar(100),
Discount DECIMAL(3,2)
)
create table UserInf(
UserName nvarchar(50),
[PassWord] varchar(50),
RealName nvarchar(50),
Gender nvarchar(10),
IDCardNo varchar(20),
Email varchar(100),
Phone varchar(11),
[Address] nvarchar(200),
Balance money,
UserStateId int foreign key REFERENCES UserState(id),
UserRoleId int foreign key REFERENCES RoleInf(id),
PicUrl varchar(200)
)
drop table UserState
drop table RoleInf
drop table UserInf

select * from UserState
select * from RoleInf
select * from UserInf
--階段1
--指導部分
/*
用戶狀態:待審核、已審核、被屏蔽
用戶角色:待審核會員、普通會員、VIP會員、超級管理員
用戶在剛注冊時狀態為待審核,角色是待審核會員,管理員進行確認和管理
*/
declare @stateid int,@roleid int
insert into UserState values('待審核')
select @stateid=@@IDENTITY--使用select為區域變數賦值//當userstate用戶狀態表中添加資料以后@stateid資料會遞增改變
insert into RoleInf values('待審核會員','','1')
set @roleid=@@IDENTITY--使用set為區域變數賦值
--使用insert select union 陳述句多行插入
insert into userinf
select 'tom123','123456','tom','1','321032198008152919','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\tom.jpg' union all
select 'jack123','admin123','jack','1','321032198612126746','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\jack.jpg' union all
select 'Slider123','as123','Slider','1','321032198208213232','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\Slider.jpg' union all
select 'Micky123','888888','Micky','1','321032198910102322','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\Micky.jpg'
GO
select * from UserState
select * from RoleInf
select * from UserInf
GO
drop table UserState
drop table RoleInf
drop table UserInf

--練習部分,向UserState、RoleInf表中插入新的資料,分別是用戶狀態資料和用戶資料
insert into UserState values ('已審核')
insert into UserState values ('被屏蔽')
insert into RoleInf values ('普通會員','','0.9')
insert into RoleInf values ('VIP會員','','0.8')
insert into RoleInf values ('超級管理員','','0.7')

--用戶表添加一個新資料用于//測驗資料
insert into UserInf values ('大神','84000508','胡偉','1','420621198909193414','[email protected]','','','1000',1,1,'d:\prt\images\Micky.jpg')
select * from UserInf
delete from UserInf where username='大神'
--審核用戶大神//把大神的UserState值修改成2('已審核')
update UserInf set Userstateid=2 where username='大神'


---------------------------檢查用戶是否已審核,如果是已審核用戶把用戶userroleid改成普通會員
declare @count int
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
select @count=COUNT(*) from userinf where username=@username and
[password]=@pwd and userstateid=2
if(@count>0)
begin
update UserInf set Userroleid=2 where username='大神'
print'登陸成功!歡迎'+@username+'您已經通過審核,已經成為普通會員'
end
else
print'登陸失敗'
go


--階段2
---------------------------IF ELSE和WHILE流程控制陳述句
create table CardType(
Id int identity(1,1) primary key,
CardtypeName varchar(20),
ImageUrl nvarchar(100),
Price money
)
create table CardState(
Id int identity(1,1) primary key,
cstate varchar(20)
)
create table CardInf(
CardNo varchar(20),
CardPwd varchar(20),
CardtypeId int foreign key references CardType(Id),
CardStateId int foreign key references CardState(Id),
CardDesc varchar(100),
validityTime datetime
)
drop table CardInf
drop table CardType
drop table CardState


select * from CardState
select * from CardType
select * from Cardinf


--添加游戲卡狀態和分類
GO
declare @stateid int=1
declare @cardtype1 int,@cardtype2 int,@cardtype3 int,@cardtype4 int
declare @cnt int=0

insert into cardstate values('未售出')
--保存Id在后續代碼中使用
set @stateid=@@identity
PRINT '此時 CardState 標識列ID為:@stateid = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardstate values('已售出')
insert into CardType values('泡泡堂游戲卡','',100)
set @cardtype1=@@identity
PRINT '此時 CardType 標識列ID為:@cardtype1 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardtype values('傳奇游戲卡','',50)
set @cardtype2=@@IDENTITY
PRINT '此時 CardType 標識列ID為:@cardtype2 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardtype values('冒險島游戲卡','',150)
set @cardtype3=@@IDENTITY
PRINT '此時 CardType 標識列ID為:@cardtype3 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardtype values('英雄聯盟游戲卡','',200)
set @cardtype4=@@IDENTITY
PRINT '此時 CardType 標識列ID為:@cardtype4 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

--游戲卡批量添加,每種型別的卡添加10張
GO
declare @seed nvarchar(8)='84000508'
declare @cnt int=0
declare @stateid int=1
if(@@ERROR=0)--沒有任何錯誤
begin
while(@cnt<50)--回圈添加卡
begin
insert into cardinf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+Convert(nvarchar(2),@cnt),--把@cnt=1 int型別轉換成nvarchar格式之后與@seed nvarchar格式拼接
CONVERT(nvarchar(2),@cnt)+@seed,--把@cnt=1 int型別轉換成nvarchar格式之后與@seed nvarchar格式拼接
5,--魔獸世界卡型別
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
while(@cnt<100)--回圈添加卡
begin
insert into CardInf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+CONVERT(nvarchar(2),@cnt),
CONVERT(nvarchar(2),@cnt)+@seed,
6,--誅仙游戲卡
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
while(@cnt<150)--回圈添加卡
begin
insert into CardInf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+CONVERT(nvarchar(4),@cnt),
CONVERT(nvarchar(4),@cnt)+@seed,
7,--天堂游戲卡
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
while(@cnt<200)--回圈添加卡
begin
insert into CardInf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+CONVERT(nvarchar(4),@cnt),
CONVERT(nvarchar(4),@cnt)+@seed,
8,--NBA籃球卡
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
end
GO

select * from CardState
select * from CardType
select * from CardInf


--練習部分,需求說明:
--實作添加用戶投訴功能(只有登陸后的用戶才能投訴)
--實作思路,
--首先必須確定用戶是否可以登錄(參考指導部分代碼),當用戶成功登陸以后,就可以進行投訴,用戶投訴就是向表中Advice中寫入資料,
create table Advice(
Id int identity(1,1) primary key,
UserName nvarchar(20),
Content nvarchar(100)
)
declare @cnt int
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
select @cnt=COUNT(*) from UserInf where username=@username and [password]=@pwd and userstateid=2
if(@cnt>0)
begin
print '登陸成功!歡迎'+@username
insert into Advice values (@username,'為什么,這破游戲還在運營,早點關門吧')
end
else
print '登陸失敗!'

GO
select * from advice


--階段3
---------------------------IF ELSE和WHILE流程控制陳述句
/*
使用if else 陳述句控制流程
使用while陳述句回圈執行sql
使用case-end陳述句進行分支判定
需求說明
實作普通會員和VIP會員的購卡功能
1,需要先確保登陸成功(即用戶名和密碼正確,并且是已經審核用戶)
2,需要檢查賬戶是否有足夠的余額,并且檢查需要購買的游戲卡狀態是否未售出
3,購買時需要一句不同角色計算出實際金額
4,將購買的游戲卡存入購物車表和購物歷史表中
實作思路
若要購卡必須先登錄,登陸時就可以確定角色,保存到區域變數中,在購卡時依據其角色確定不同的則扣,
購卡時要先驗證用戶的賬戶余額,然后驗證游戲卡狀態,將選擇的卡放入購物車,保存到ShoppingCard表中,并記錄到購卡歷史表ShopHistory中,
實作步驟
(1),新建查詢,保存為Chap2-3.sql
(2),在Chap2-3.sql中撰寫T-sql代碼,根據用戶名就,密碼,用戶狀態ID查詢資料行將查詢的資料行賦值給區域變數@cnt
代碼
登陸
*/
--新建ShopHistory和shoppingCart表
create table ShopHistory(
Id int identity(1,1) primary key,
UserName nvarchar(50),
CardNo nvarchar(50),
ShopTime datetime
)
create table shoppingCart(
Id int identity(1,1) primary key,
UserName nvarchar(50),
CardTypeId int,
Num int
)

select * from ShopHistory
select * from shoppingCart

--用戶表
select * from UserState
select * from RoleInf
select * from UserInf
--游戲卡
select * from CardState
select * from CardType
select * from Cardinf

--------------------------------購卡代碼START
go
declare @cnt int=0
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
declare @roleid int
declare @stateid int=2
select @cnt=COUNT(*) from UserInf where username=@username and [password]=@pwd and UserStateId=@stateid--根據用戶名就,密碼,用戶狀態ID查詢資料行將查詢的資料行賦值給區域變數@cnt

--(3)根據變數@cnt是否大于0判斷用戶能否登陸成功,如果登陸成功,還要判斷此用戶的賬戶余額是否足夠購買兩張'魔獸世界游戲卡'
--代碼(接上一代碼)
if(@cnt>0)
begin
print @username+'您好!'
print'1.登陸成功!'
--開始購卡(購買兩張魔獸世界游戲卡)
--檢查賬戶是否有足夠的余額,還要檢查要購買的游戲卡狀態是否為未售出
declare @balance money --保存賬戶余額
select @balance=balance from UserInf where UserName=@username--獲取用戶的余額
select @roleid=UserRoleid from UserInf where Username=@username--獲取用戶的會員級別
declare @requiremoney money--保存需要用掉的金額
declare @dicount decimal(10,2)--不同角色的則扣
select @dicount=discount from RoleInf where Id=@roleid--根據會員級別獲取打折率
--魔獸世界游戲卡型別ID為1
select @requiremoney=@dicount*price*2 from CardType where Id=1--獲取需要用掉的金額
if(@balance>=@requiremoney)--如果用戶賬戶金額>=需要用掉的金額
begin
print'2.開始買卡!'
--滿足了余額要求,再檢查游戲卡狀態
declare @state int--用于檢查游戲卡狀態變數
select @state=CardStateid from Cardinf where CardNo='200301452'--檢查游戲卡的狀態

if(@state=1)--如果游戲卡的狀態為未出售
begin
print'3.點卡200301452未出售!'
select @state=CardStateid from CardInf where CardNo='200301453'--檢查游戲卡的狀態

if(@state=1)
begin
print'4.點卡200301453未出售!'
--購卡成功,添加資料到兩張表
insert into ShopHistory values (@username,'200301452',GETDATE())
insert into ShopHistory values (@username,'200301453',GETDATE())
insert into shoppingCart values (@username,1,2)

if(@@ERROR=0)
begin
print'5.成功添加資料到ShopHistory和shoppingCart!'
update CardInf set cardstateid=2 where cardno in ('200301452','200301453')
update UserInf set Balance -= @requiremoney where username=@username
if(@@ERROR=0)
begin
print'6.購卡成功!更新CardInf和UserInf,完成扣費和卡狀態更新已售出'
end
end
end
end
end
else
print @username+',您的賬戶余額不足,請在線充值'
end
go
--------------------------------購卡代碼END
--執行完畢后,檢查表shoppingcart,shophistory,userinf,cardinf的資料
select * from CardInf
select * from UserInf
select * from ShopHistory
select * from shoppingCart
--------------------------------------------

---------------------------上機作業
/*
1,添加一個管理員賬戶,用戶名為'admin',密碼為'admin123'
2,用戶tom123回款500元
3,匯款經過管理員admin審核以后可以使用
4,匯款狀態有3種:待審核,已審核,掛起
實作思路
先添加匯款狀態和管理員賬號
*/
create table ApproveState(
Id int identity(1,1),
[State] nvarchar(50)
)
create table PostRecord(
Id int identity(1,1) primary key,
UserName nvarchar(20),
Bank nvarchar(50),
[Money] money,
PostTime datetime,
PostDesc nvarchar(225),
ApproveStateId int
)
------------添加匯款狀態------------
declare @state1 int,@state2 int,@state3 int
insert ApproveState values('待審核')
set @state1=@@IDENTITY
insert ApproveState values('已審核')
set @state2=@@IDENTITY
insert ApproveState values('掛起')
set @state3=@@IDENTITY
------------添加管理員------------
declare @admin nvarchar(20)='admin'
declare @adminpwd nvarchar(20)='admin123'
insert into UserInf values(@admin,@adminpwd,'胡偉',1,'420621198909193414','[email protected]','','',888888,2,4,'')
------------匯款審核------------
go
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
declare @stateid int=2
declare @money money=500
declare @cnt int=0
declare @id int
select @cnt=count(*) from UserInf where username=@username and [password]=@pwd and UserStateId=@stateid
if(@cnt>0)
begin
print '登陸成功!歡迎'+@username
insert into PostRecord values (@username,'中國工商銀行',@money,GETDATE(),'購買魔獸世界游戲卡','')
set @id=@@identity
if(@@ERROR=0)
begin
print'向PostRecord表中插入購買資訊成功,等待審核!'
update PostRecord set ApproveStateId= 2 where Id=@id
if(@@ERROR=0)
begin
print'審核成功!正在轉賬到賬戶中!'
update UserInf set Balance += @money where UserName=@username
if(@@ERROR=0)
begin
print'充值成功!'
select balance as 您當前金額 from UserInf where username=@username
end
end
end
end
else
print'登陸失敗!'+@username+'請核實再登陸'
go
select * from PostRecord
select * from UserInf
select * from ApproveState
--------------------------------------------------------------------------------深入SQL高級子查詢

use HR
select * from Employee
select * from Salary
select * from Expertise
select * from Department

--查詢編號為'E001'的員工屬于同一個部門的員工
--使用變數方法
declare @deptno nvarchar(10)--定義一個變數記錄部門
select @deptno=DeptNo from Employee where EmpNo='E001'
select * from Employee where DeptNo=@deptno and EmpNo <> 'E001'--查找這個部門的所有員工資訊除了'E001'工號
--使用子查詢
select * from Employee where deptno=(select deptno from Employee where EmpNo='E001') and EmpNo<>'E001'

--查詢工資在5000元以上,并且擁有的技能等級最高的員工資訊
--這個查詢涉及Employee,Salary,Expertise

--1.查詢工資大于5000的員工工號
select EmpNo from Salary where salary>5000

--2.根據1查村出最高技能等級
select MAX(SkillLevel) from Expertise where EmpNo in (select EmpNo from Salary where salary>5000)

--3.根據2查詢出此員工工號
select Empno from Expertise where SkillLevel=(select MAX(SkillLevel) from Expertise where EmpNo in (select EmpNo from Salary where salary>5000))

--4.根據3查詢出此員工資訊
select * from Employee where Empno=(select Empno from Expertise where SkillLevel=(select MAX(SkillLevel) from Expertise where EmpNo in (select EmpNo from Salary where salary>5000)))

---------------------------------------------UPDATE,DELETE,INSERT陳述句中使用子查詢
--1,在update陳述句中使用查詢
select * from Department
select * from Employee
select * from Expertise
select * from Salary

--查詢'E010'所在的部門
select DeptNo from Department where Principal='E010'

--查詢和'E010'在同個部門的員工
select EmpNo from Employee where DeptNo=(select DeptNo from Department where Principal='E010')

--根據員工編號更新技能等級
update Expertise set SkillLevel+=1 from Expertise where EmpNo in (select EmpNo from Employee where DeptNo=(select DeptNo from Department where Principal='E010'))

--2,在Delete陳述句中使用查詢

--查詢技術部所在的部門
select DeptNo from Department where DeptName='技術部'

--根據部門查詢所有員工的工號
select EmpNo from Employee where DeptNo=(select DeptNo from Department where DeptName='技術部')

--查詢準備洗掉的這些資料
select * from Salary where EmpNo in (select EmpNo from Employee where DeptNo=(select DeptNo from Department where DeptName='技術部')) and DATEDIFF(YYYY,StartTime,'2014-10-10 00:00:00')>=5

--最后洗掉這個資料
delete from Salary where EmpNo in (select EmpNo from Employee where DeptNo=(select DeptNo from Department where DeptName='技術部')) and DATEDIFF(YYYY,StartTime,'2014-10-10 00:00:00')>=5

---------------------------------------------在INSERT陳述句中使用子查詢
--基本語法: INSERT INTO 表名(欄位串列) SELECT 欄位串列 FROM 表名
--根據其它表的資料插入到被插入的表中,要求被插入的表必須存在

--備份整個表語法: select * into EmpHistory from Employee

--備份表結構: select * into EmpHistory from Employee where 1<>1
--備份表結構: select top 0 * into EmpHistory from Employee

--使用 insert into 被插入表 子查詢陳述句 where 條件 功能備份資料,要求被插入的表必須存在
--使用 select * into 被插入表 from 原表 where 條件 功能備份資料,被插入的表必須不能存在

select * from Employee
select * from EmpHistory

--(1)備份表結構
select * into EmpHistory from Employee where 1<>1

--(2)使用子查詢將表Employee中的3個離職員工資訊添加到表EmpHistory
--使用 insert into 被插入表 子查詢陳述句 where 條件 功能備份資料,要求被插入的表必須存在
insert into EmpHistory select * from Employee where EmpNo in ('E002','E003','E008')

--使用 select * into 被插入表 from 原表 where 條件 功能備份資料,被插入的表必須不能存在
select * into EmpHistory from Employee where EmpNo in ('E002','E003','E008')

--(3)從員工技能表和員工表中洗掉這3個已經離職的員工資訊
delete from Employee where EmpNo in ('E002','E003','E008')
delete from Expertise where EmpNo in ('E002','E003','E008')

select * from Employee
select * from Expertise


---------------------------------------------高級子查詢陳述句
/*---------------------使用IN,NOT IN的子查詢
當子查詢與比較運算一起使用時,要求子查詢回傳的結果必須是一行記錄或空記錄,
如果子查詢回傳的結果是多行,可以將比較運算子改為IN,IN后面的子查詢允許回傳多行記錄,用于從一個范圍來限制主查詢條件
*/
--1查詢技能的級別在3級以上的員工資訊

select * from Employee where empno in (select EmpNo from Expertise group by EmpNo having MAX(SkillLevel)>=3)

--2洗掉Phone表中重復的資料
select * from Phone

--按Phone,OfficeCode分組(多列分組)
--查詢出經過多列分組之后Id較大的資料//指最新資料
select MAX(Id) from Phone group by Phone,OfficeCode
--洗掉資料不包括分組之后Id較大的資料//指最新資料
delete from Phone where id not in (select MAX(Id) from Phone group by Phone,OfficeCode)


select * from EmpHistory
select * from TimeWork
select * from Employee

--查詢考情表中有但員工表中沒有的記錄
select * from TimeWork where EmpNo not in (select empno from Employee where Employee.EmpNo=TimeWork.EmpNo)

--查詢員工表中所有員工編號
select empno from Employee group by empno
--查詢考情表中有但員工表中沒有的記錄
select * from TimeWork where EmpNo NOT IN (select empno from Employee group by empno)


--查詢技術部有哪些員工
select * from Department
select * from Employee
--
select * from Employee where exists (select * from Department where Department.DeptNo=Employee.DeptNo and DeptName='技術部')--相關子查詢

select * from Employee where DeptNo=(select DeptNo from Department where DeptName= '技術部')--獨立子查詢

select * from (select EmpNo,EmpName,Empaddress,Empphone,Birthday,Hiredate,Employee.DeptNo,Officecode,DeptName,Principal from Employee left join Department on Employee.DeptNo=Department.DeptNo) as ED where DeptName='技術部'--獨立子查詢

select EmpNo,EmpName,Empaddress,Empphone,Birthday,Hiredate,Employee.DeptNo,Officecode from Employee join Department on Department.DeptNo=Employee.DeptNo and DeptName='技術部'

---------------------使用exists,not exists的子查詢
--exists與子查詢在一起使用,用來對子查詢的查詢結果進行存在的測驗,只要子查詢的結果有一個行或者一行以上的資料就回傳真,否則回傳假,
-- 因為結果只取決于是否回傳行,而不取決于這些行的內容,所以exists查詢的條件子查詢輸出串列通常是無關緊要的,只要有一個欄位即可,

--查找出具有C#技能的員工,并顯示詳細資訊

select * from Employee
select * from Expertise
select * from Skill

select * from Employee where exists (select * from Expertise where Expertise.EmpNo=Employee.EmpNo and SkillId=(select SkillId from Skill where SkillName='C#'))


---------------------使用ALL的子查詢
/*
通過比較運算子將一個運算式的值或列值與子查詢回傳的一列值中的每一行進行對比
*/
select * from Salary
select * from Department
/*
分析
1.先查詢select Principal from Department,從部門表中查詢出所有部門負責人的編號
2.再查詢select Salary from Salary where EmpNo in(select Principal from Department),從工資表中查詢出所有的部門負責人的工資
3.執行整個查詢陳述句,Salary表中的salary列的資料依次和(部門負責人的工資)列資料進行對比,滿足條件的篩選出來
*/
select EmpNo , Salary
from Salary
where Salary > all(select Salary from Salary where EmpNo in(select Principal from Department))

---------------------使用ANL/SOME的子查詢
/*
ANY與子查詢在一起使用時,按照比較運算子,運算式或欄位對子查詢的結果每一行進行依次計算和比較,
*/
--查詢只要員工工資大于任何一個部門負責人,就顯示這些員工的資訊
select EmpNo, Salary
from Salary
where Salary > some (select Salary from Salary where EmpNo in (select Principal from Department)) and EmpNo not in (select Principal from Department)

select EmpNo , Salary
from Salary
where Salary > (select MIN(Salary) from Salary where EmpNo in (select Principal from Department)) and EmpNo not in (select Principal from Department)


---------------------使用別名的相關子查詢//沒有懂
select * from Salary
select EmpNo from Salary

select * from Expertise
select empNo from Expertise

select * from Employee
select empNo from Employee

select * from Employee e join Expertise p on e.EmpNo=p.EmpNo

select * from Salary s join Employee e on e.EmpNo=s.EmpNo

--=要求查詢在員工表與技能表中都存在,并且月工資為5000元的一個員工,這個查詢會涉及到3張表:Employee,Expertise,Salary
--57頁
select distinct e.empno,e.empname
from Employee e join Expertise p on e.EmpNo=p.EmpNo where 5000 in (select Salary from Salary s where e.empNo=s.EmpNo)

--上機階段1
---------------------------使用基本子查詢,in子查詢
/*
訓練內容
使用基本子查詢
1,在update陳述句中使用子查詢
2,在insert陳述句中使用子查詢
3,使用in/not in的子查詢
需求說明
實作用戶“jack123”購卡流程:用戶“jack”想一次購買5張NBA籃球卡,要求實作此用戶的購卡流程,
購買游戲卡需要6步驟:
1,查詢用戶需要購買的卡的型別數量是否充足
2,檢查用戶賬戶的余額是夠足夠購買這些卡
3,將購買的游戲卡保存到購物歷史紀錄中
4,將購買的游戲卡資訊保存到購物車
5,跟新用戶的賬戶余額
6,跟新游戲的狀態
*/

--代碼實作

select * from CardInf
select * from UserInf
select * from shoppingCart
select * from shophistory

--1:查詢用戶需要購買的卡的型別數量是否充足
--說明:檢查可以出售的NBA籃球卡是否夠5張使用子查詢來查詢卡的型別ID和狀態ID
GO
declare @CardTypeName nvarchar(20)='冒險島游戲卡'
declare @UserName nvarchar(20)='葫蘆娃'
declare @cnt int
select @cnt=COUNT(*) from CardInf where CardTypeId=(select id from CardType where CardTypeName=@CardTypeName)
and CardStateId=(select id from CardState where cstate='未售出')
print '游戲卡還有'+convert(nvarchar,@cnt)
if(@cnt>=5)
begin
--2:檢查用戶賬戶的余額是夠足夠購買這些卡
--說明:因為用戶會依據角色有一定的折扣,所以用5張卡的面額乘以折扣率
--2.1:查詢賬戶的余額
declare @balance money,@requiremoney money
select @balance=balance from UserInf where UserName = @UserName
print @UserName+'賬戶的余額'+convert(nvarchar,@balance)
--2.2購買5張卡需要的余額
select @requiremoney=5*price from CardType where Id=(select id from CardType where CardTypeName=@CardTypeName)
print '購買5張卡的價格'+convert(nvarchar,@requiremoney)
--2.3根據會員等級打折
set @requiremoney=@requiremoney*(select discount from RoleInf where id=(select userroleid from userinf where username=@UserName))
print '打折后需要的價格'+convert(nvarchar,@requiremoney)
if(@balance>=@requiremoney)
begin
--3:將購買的游戲卡保存到購物歷史紀錄中
--說明:取出NBA籃球卡的前五張,保存到購卡歷史紀錄中,因為已經購買了游戲卡,在后面的代碼中還要修改其狀態,所以使用table型別的變數進行保存
--3.1:5張卡號后面還要使用,所以保存到變數中
declare @temptable table(id int identity(1,1),CardNo nvarchar(20))
insert into @temptable select top 5 cardno from cardinf
where cardstateid=(select id from cardstate where [cstate]='未售出') and cardtypeid=(select id from cardtype where cardtypename=@CardTypeName)
--3.2:回圈購卡
declare @id int=1
while(@id<=5)
begin
insert into shophistory values(@UserName,(select cardno from @temptable where id=@id),getdate())
set @id+=1
end
--4:將購買的游戲卡資訊保存到購物車
--說明:@@ERROR全域變數等于0,保證了它前面的T-SQL已經正確執行,在insert陳述句中使用了子查詢,查詢出游戲卡的型別,在更新已購買的游戲卡狀態時,
-- 在UPDATE陳述句中也使用了子查詢,批量更新這5條游戲卡的狀態ID為 2 (已售出),變數@temptable保存已經選購的游戲卡的卡號
if(@@ERROR=0)
begin
insert into shoppingcart values(@UserName,(select id from cardtype where cardtypename=@CardTypeName),5)
--4.1:更改游戲卡狀態
update cardinf set cardstateid=2 where cardno in (select cardno from @temptable)
end
--5:更新用戶的賬戶余額
if(@@ERROR=0)
begin
declare @surplus money
update UserInf set balance -= @requiremoney where UserName=@UserName
select @surplus=balance from userinf where UserName=@UserName
print '購買成功!您的賬戶余額為'+convert(nvarchar,@surplus)
end
end
else
print @username+'您的賬戶余額為'++convert(nvarchar,@balance)+',余額不足,請在線充值!'
end
GO
/*練習部分
需求說明
使用子查詢統計在所有已經銷售的游戲卡中滯銷的游戲卡型別,熱銷的游戲卡型別及還沒有銷售量的游戲卡型別,
其總銷量小于10張的為滯銷的游戲卡型別,總銷售量大于1000張的為熱銷的游戲卡型別,總銷售量為0的是沒有銷售量的游戲卡型別
實作思路
以查詢滯銷游戲卡為例:使用group by和having查詢出銷售量小于10的游戲卡型別ID,然后依次作為WHERE條件,使用in與這些結果比較,查詢出游戲卡的類別名稱
*/
select * from CardType
select * from CardInf
select * from ShophiStory
select * from UserInf
select * from ShoppingCart
select * from CardType


update UserInf set balance=10000 where username='葫蘆娃'

select cardtypename from CardType where id =ANY (select c.CardTypeId from ShophiStory s,CardInf c where s.CardNo = c.CardNo group by c.CardTypeId having count(s.CardNo)<10)

use Company_DB
select
*,
'銷售情況'=case
when 銷售數量>=10 then '熱銷'

when 銷售數量>0 then '滯銷'

else '還沒銷售'
end
FROM
(select cardtypename, count(ShophiStory.cardno) as 銷售數量 from CardType,CardInf,ShophiStory
where CardInf.CardTypeId=CardType.id AND CardInf.cardno=ShophiStory.cardno
GROUP by cardtypename) as a



--代碼實作
--查找銷量小于10張的為滯銷卡的名稱
select cardtypename from CardType where id =ANY (select c.CardTypeId from ShophiStory s,CardInf c where s.CardNo = c.CardNo group by c.CardTypeId having count(s.CardNo)<10)

--查找沒有銷售量的游戲卡名稱
select cardtypename from CardType where id in (select c.CardTypeId from CardInf c left join ShophiStory s on s.CardNo = c.CardNo group by c.CardTypeId having COUNT(s.CardNo)=0)


--上機階段2
---------------------------使用相關子查詢,ANY子查詢
/*
訓練內容
使用相關子查詢
1,相關子查詢
2,多表鏈接查詢
3,Any子查詢
需求說明
1,在用戶每次購買游戲卡,系統都應該根據其消費金額為用戶升級(指角色升級),
角色級別越高,用戶則扣越高,要求實作用戶角色升級功能,

2,用戶角色升級的條件為:單日消費達到200元或總消費達到1000元時可升一級,
但是最高不能升級成‘超級管理員’,要求分別使用相關子查詢和聯接查詢實作

實作思路
思路一:使用連接查詢
用戶的消費記錄保存在購物歷史紀錄表ShophiStory中,用戶購買的型別不同,價格就不同所以要聯接表CardType查詢價格,
同時,要統計用戶每天購卡的金額就必須根據不同型別的卡將每日購買的金額進行分組統計,
因為單張卡的型別ID在表CARDINF中所以必須與表CARDINF做聯接查詢
思路二:使用相關子查詢
先通過相關子查詢查詢出用戶‘大神’所有買的所有卡的卡號和金額
*/

----------代碼實作
----------相關查詢
/*說明:1,明確外層查詢的表和列
2,明確內層查詢的表和列
3,明確內層查詢與外層查詢的主外鍵關系
4,明確外層查詢的where條件
*/
SELECT
ss.username,
ss.cardno,
ss.shoptime,
(
SELECT price from CardInf ci,CardType ct WHERE ci.cardtypeid=ct.id AND ss.cardno=ci.cardno
)
from ShophiStory as ss
WHERE ss.username = '大神'


SELECT
ShophiStory.username,
ShophiStory.cardno,
ShophiStory.shoptime,
(
SELECT price from CardInf,CardType WHERE CardInf.cardtypeid = CardType.id and CardInf.cardno = ShophiStory.cardno
)
from ShophiStory
WHERE username = '大神'


select
ShophiStory.username,
ShophiStory.cardno,
ShophiStory.shoptime,
(SELECT price from CardInf join CardType on CardInf.CardTypeid=CardType.id and CardInf.cardno=ShophiStory.cardno)
from ShophiStory
where username='大神'


----------連接查詢
select * from ShophiStory
select * from CardInf
select * from CardType

SELECT
ss.username,
ss.cardno,
ss.shoptime,
ct.price
from CardInf ci,CardType ct,ShophiStory ss WHERE ss.cardno=ci.cardno AND ci.cardtypeid=ct.id AND ss.username='大神'


/*實作步驟
方法一:連接查詢實作
*/
--對用戶'葫蘆娃'的角色ID進行升級,按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計),使用any檢查,只要有一天消費金額大于等于200,即可升級,
--獲取管理員的角色ID和當前用戶的角色ID
--代碼實作
use Company_DB
go
--1,查詢用戶當前的角色
declare @role int
select @role=userroleid from UserInf where username='葫蘆娃'--獲取用戶的身份等級
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where rolename <> '超級管理員'--獲取管理員的身份等級
if(@role<@adminrole)--如果用戶的身份等級低于管理員身份
begin

--獲取需要升級的用戶角色等級ID,該角色等級ID是比用戶當前的角色等級ID大的所有的角色等級ID中最小的一個(每次只能升級一級),在第二步的begin與end之間輸入代碼進行判斷
declare @sharprole int -- 需要升級的角色等級ID
select @sharprole=MIN(id) from RoleInf where id > @role --從角色等級表中取出用戶要升級的角色等級ID

--對用戶'葫蘆娃'的角色ID進行升級,按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計),使用any檢查,只要有一天消費金額大于等于200,即可升級,
-- 在第三步的基礎上繼續輸入更新用戶角色的代碼:
--聯接查詢方法實作;
update UserInf
set userroleid=@sharprole
where username='葫蘆娃' and
200 < any
(select SUM(ct.price) as '每日消費' from ShopHistory s,CardInf ci,CardType ct where s.CardNo=ci.cardno and ci.cardtypeid=ct.id and s.UserName='葫蘆娃'
group by CONVERT(char(10),s.ShopTime,120))--把datetime型別轉換成char型別保yyyy-mm-dd

if(@@ERROR=0)--執行未出錯
print 'OK'
end
go

--按用戶消費金額的總額進行升級(總消費滿1000元即可升級),
use Company_DB
go
declare @role int
select @role=userroleid from UserInf where UserName ='葫蘆娃'
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where RoleName <> '超級管理員'
if(@role<@adminrole)
begin
declare @sharprole int
--要升級到角色,一次只能升級一次
select @sharprole=MIN(id) from RoleInf where Id > @role
update userinf
set UserRoleId=@sharprole
where UserName='葫蘆娃'
and (select SUM(ct.Price) as '總消費' from ShopHistory s,CardInf ci,CardType ct where s.CardNo=ci.CardNo and ci.CardTypeId=ct.Id and s.UserName='葫蘆娃')>=1000
if(@@ERROR=0)--執行未出錯
print 'OK'
end
go

/*
方法二:相關子查詢實作
*/
--對用戶'葫蘆娃'的角色ID進行升級,按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計)
--獲取管理員的角色ID和當前用戶的角色ID

--思路參考代碼:!!!
--查詢括號中的類容是關鍵 他通過CardInf表與CardType表進行聯接,然后與外部的ShopHistory表進行逐步行篩選(相關子查詢),查詢的結果作為一個獨立值,其別名為sumPay
select
SUM(re.sumPay) sum_pay
from
(select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃') as re
group by
CAST(CAST(year(re.shoptime)as varchar)+'-'
+CAST(month(re.shoptime)as varchar)+'-'
+CAST(day(re.shoptime)as varchar)as datetime)

select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃'

--思路細節:!!!
select price from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id

select * from CardInf as ci, CardType as ct,ShopHistory as s where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo and s.UserName='葫蘆娃'

select SUM(price) from CardInf as ci, CardType as ct,ShopHistory as s where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo and s.UserName='葫蘆娃'

select SUM(price) from CardInf as ci, CardType as ct,ShopHistory as s where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo and s.UserName='葫蘆娃' group by CONVERT(char(10),s.ShopTime,120)

select * from ShopHistory
select * from UserInf
select * from RoleInf
update UserInf set UserRoleId=1 where UserName='大神' or UserName='葫蘆娃'

--代碼實作
----按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計)
use Company_DB
go
declare @role int
select @role=userroleid from UserInf where UserName='葫蘆娃'
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where RoleName <> '超級管理員'
if(@role<@adminrole)
begin
declare @sharprole int
--要升級成的角色
select @sharprole=MIN(id) from RoleInf where Id>@role
update userinf set userroleid = @sharprole
where username='葫蘆娃'
and 1000 < any
(select SUM(re.sumPay) sum_pay
from
(select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃') as re
group by
CAST(CAST(year(re.shoptime)as varchar)+'-'
+CAST(month(re.shoptime)as varchar)+'-'
+CAST(day(re.shoptime)as varchar)as datetime))
if(@@ERROR=0)
print 'ok'

end
go

----按用戶消費金額的總額進行升級(總消費滿1000元即可升級),
use Company_DB
go
declare @role int
select @role=userroleid from UserInf where UserName='葫蘆娃'
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where RoleName <> '超級管理員'
if(@role<@adminrole)
begin
declare @sharprole int
--要升級成的角色
select @sharprole=MIN(id) from RoleInf where Id>@role
update userinf set userroleid = @sharprole
where username='葫蘆娃'
and 1000 < any
(select SUM(re.sumPay) sum_pay
from
(select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃') as re)
if(@@ERROR=0)
print 'ok'
end
go



--------------------------------------------------------------------------------函式和存盤程序
/*
1、函式
定義:一種封裝一潭訓多條SQL陳述句的結構
好處:
減少代碼冗余,提高代碼重用性
預編譯的,提高代碼執行效率
分類:
聚合函式、系統函式、自定義函式(標量值函式 和 表值函式)
標量值函式:回傳值為一個資料
語法:
create function 函式名
(
引數1 型別,引數2 型別,......引數n 型別
)
returns 回傳值型別
as
begin
函式體
return 值
end
表值函式:回傳值為一個資料表
分類:多陳述句表值函式和行內表值函式
多陳述句表值函式:
語法:
create function 函式名
(
引數1 型別,引數2 型別,......引數n 型別
)
returns 回傳值 table(表結構)
as
begin
函式體
return
end
行內表值函式:
語法:
create function 函式名
(
引數1 型別,引數2 型別,......引數n 型別
)
returns table
as
return (查詢)
*/

---------------------------5.1.2標量值函式
/*
標量值函式的回傳值是基本資料型別的單個值或單個值得運算式,函式體既可以是一條陳述句(可以省略begin end),
也可以是多條陳述句(多條陳述句必須放在begin end之間)
標量值函式可以被另外的標量值函式或表值函式呼叫
*/
--5.1函式的功能是通過引數傳入員工的編號,回傳該員工的工資標準
use HR
go
create function getEmpSalary( @empno varchar(20) ) --引數
returns money --回傳值型別
begin
declare @salary money; --最新工資資料
select @salary=Salary from Salary where Salary = (select top 1 Salary from Salary where EmpNo=@empno order by StartTime desc)
return @salary --回傳值
end
go

--5.2直接輸出標量值函式的回傳值
go
select dbo.getempsalary('E006') as 員工E006的工資標準
go

--5.3將標量值函式的回傳值存入變數
declare @salary money
select @salary = dbo.getEmpSalary('e006')
print '員工E006的月薪是'+convert(varchar(10),@salary)

--5.4新創建函式getDateMaxSlary,在該函式中呼叫示例5.1中創建的getEmpSalary,用來統計一個部門的最高月薪
use HR
go
create function getDeptmaxsalary(@deptno varchar(10)) returns money --定義函式名稱和形參變數
as
begin declare @maxsalary money=0 --定義保存部門的最高月薪
/*因為一個部門有多少員工,使用個基本型別的變數無法保存這些員工的編號,所以使用table型別的變數臨時保存*/
declare @emp table(id int identity(1,1),empno varchar(10))
--將這個部門的員工編號保存到table型別的變數中
insert into @emp select empno from employee where deptno=@deptno
declare @cnt int = 0,@i int=0 --回圈變數
declare @empno varchar(10) --保存員工編號
declare @salary money --保存員工工資
select @cnt=count(*) from @emp --確定回圈次數,查新新臨時表中有幾條資料
while(@i<@cnt)
begin
--查詢每個員工的編號
select @empno=empno from @emp where id=(@i+1)
--呼叫自定義的標量值函式計算當前員工的工資標準
select @salary=dbo.getempsalary(@empno)
if(@salary>@maxsalary)
begin
set @maxsalary=@salary --將最高的工資保存到變數@maxsalary中
end
set @i+=1
end
return @maxsalary
end --回傳最高工資
go

--5.5傳入部門編號呼叫改方法
select * from Department
use HR
go
select dbo.getDeptmaxsalary('d03') as 最高工資
go


---------------------------5.1.3表值函式
--1,多陳述句表值函式
--多陳述句表值函式要求回傳型別為table型別
--需求:回傳所有員工的當前工資標準
use HR
go
--函式執行完畢后回傳table型別的變數@salarytable
create function getEmployeesSalary()
returns @salarytable table(
id int,
EmpNo nvarchar(20),
Salary money,
StartTime datetime
)
as
begin
--為table型別的變數賦值 insert into @salarytable
insert into @salarytable
select * from Salary where StartTime in (select MAX(StartTime) from Salary group by EmpNo)
return --無需再寫值或運算式,直接回傳變數@salarytable
end
go

--使用getEmployeesSalary表值函式
select * from dbo.getEmployeesSalary()
--使用原表salary
select * from Salary


--5.8帶引數的表值寒素
--需求:通過傳入部門編號,回傳指定部門所有員工的當前工資標準
use HR
go
--引數要求傳入的是部門編號
create function getEmpSalaryByDept(@deptno varchar(20))
returns @salarytable table
(
id int,
EmpNo nvarchar(20),
Salary money,
StartTime datetime
)
as
begin
--在子查詢中使用到引數@deptno
insert into @salarytable --查詢最新入職時間 --查找對應部門的員工編號 --按員工分組
select * from salary where starttime in (select max(starttime) from salary where empno in (select empno from employee where deptno=@deptno) group by empno)
return
end
go


--5.9行內表值函式
--根據傳入的引數回傳員工的技能
use HR
go
create function getEmpertiseByEmp(@empno varchar(10))
returns table
as return (select * from Expertise where EmpNo=@empno)
go

select * from getEmpertiseByEmp('e003')
select * from Expertise


----------------------------------------------------存盤程序!!!!!!!
--------------------------------------------------------------------------------------------存盤程序!!!!!!!
------------常用的系統存盤程序
use master
go
exec sp_renamedb 'HR','hr_prj' --改變單用戶訪問的資料庫名稱
go
use cardsale --進入到名稱為hr_prj的資料庫下
go
exec sp_databases --回傳當前實體中的所有資料庫的基本資訊
exec sp_tables --查看資料庫hr_prj中可查看物件的串列
exec sp_help employee --查看表employee的所有資訊
exec sp_helpconstraint employee --查看表employee的約束
exec sp_helptext 'dbo.vw_empsalary'--查看識圖vm_empsalary的定義
exec sp_stored_procedures --查看當前資料庫中所有的存盤程序
use master
go
exec sp_renamedb 'hr','HR'--將資料庫名稱更改回來
go


use master
go
--使用系統存盤程序sp_configure啟用高級選項
exec sp_configure 'show advanced options',1
go
reconfigure --重新配置
go
exec sp_configure 'xp_cmdshell',1 --啟用xp_cmdshell擴展程序
go
reconfigure --重新配置
go
exec xp_cmdshell 'mkdir d:\prj' --呼叫dos命令'mkdir'創建作業系統目錄
if(exists(select * from sysdatabases where name='onlineexam'))
drop database onlineexam
go
create database OnLineExam
on
(
name='OnLineExam_data',
filename='d:\prj\OnLineExam_data.mdf',
size=5mb
)
log on
(
name='OnLineExam_log',
filename='d:\prj\OnLineExam_log.ldf',
size=5mb
)
go
exec xp_cmdshell 'dir d:\prj\' -- 查看創建資料庫檔案
------------用戶自定義存盤程序
------------------------------1.創建不帶引數的存盤程序
--創建存盤函式程序,顯示HR資料庫中月薪最低的員工
use hr
go
if exists(select * from sysobjects where name='UP_Salary_SelectMinSalary')
drop procedure UP_Salary_SelectMinSalary
go
create proc up_Salary_SelectMinSalary
as
select
empname,
minsal.salary
from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary) as minsal,
Employee
where minsal.EmpNo=Employee.empno
--思路
select MAX(StartTime)from Salary group by EmpNo --查詢記錄員工工資的最后記錄時間
select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo) --查詢工資表,根據每個員工的最后記錄時間
select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary --查詢最低工資和員工號
select * from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary) as minsal,Employee where minsal.EmpNo=Employee.empno --聯接查詢最低工資員工的資訊
select empname,minsal.salary
from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary) as minsal,Employee where minsal.EmpNo=Employee.empno --聯接查詢最低工資員工的工資和姓名
--執行存盤程序,查詢工資最低的員工
use hr
go
exec UP_Salary_SelectMinSalary
------------------2.創建帶引數的存盤程序
--創建測驗表
create table timework(
empno nvarchar(20),
[state] nvarchar(20),
dtime datetime
)
use hr
go
if exists(select * from sysobjects where name='UP_TimeWork_Insert')
drop procedure UP_TimeWork_Insert
go
create proc UP_TimeWork_Insert
(
--輸入引數串列
@empno varchar(10), --傳入的員工編號
@state nvarchar(20), --傳入的作業狀態
@dtime datetime --傳入的作業日(注意:最后一個引數不能有逗號)
)
as
--存盤程序執行添加資料(形參串列)
insert into timework values(@empno,@state,@dtime)
if(@@ERROR=0)
print 'ok'
else
print 'error'
go
exec UP_TimeWork_Insert 'E005','休假','2010-1-1'
go
--查詢結果
select * from timework
------------------------3.帶輸出引數的存盤程序
--如果需要存盤程序回傳一個值或者多個值,可以使用輸入引數,輸出引數必須在存盤程序定義時使用output關鍵字進行宣告
--存盤程序可以通過return回傳值,但一般只是回傳一些執行狀態值
--創建一個帶輸入引數和輸出引數的存盤程序UP_Salary_Insert,當使用輸入引數執行添加一條工資標準后,再通過輸出引數回傳工資表中最高工資的員工
use Company_DB
go
if exists(select * from sysobjects where name='UP_Salary_Insert')
drop procedure UP_Salary_Insert
go
create proc UP_Salary_Insert
(
@maxsalary money output, --傳出引數,最高工資標準
@empname nvarchar(20) output, --傳出引數,工資最高的員工姓名
@empno nvarchar(10),
@salary money=10000,
@stime datetime
)
as
insert into Salary values(@empno,@salary,@stime)
--為傳出引數賦值
select @empname=empname,@maxsalary=maxsal.salary
from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in(select MAX(StartTime) from Salary group by EmpNo ))as sal order by sal.Salary desc) as maxsal,Employee
where maxsal.empno=employee.empno
--在呼叫帶傳出引數的存盤程序時,需要先定義對應的變數作為實際引數,并且在實際引數后面必須使用output關鍵字,
-- 執行存盤程序成功后,就可以通過變數得到存盤程序傳出的引數值
--先定義變數,與傳出引數保持型別一致
declare @maxsal money,@emp nvarchar(20)
--執行存盤程序時,將變數作為實際引數,并使用output關鍵字進行說明
execute UP_Salary_Insert @maxsal output,@emp output,'E011',13000,'2010-01-01'
--執行完畢后,通過變數得到存盤程序傳出的值
print @emp
print '工資'+convert(nvarchar(20),@maxsal)
go
--------------------4.錯誤處理
use Company_DB
go
if exists(select * from sysobjects where name='UP_Salary_Insert')
drop procedure UP_Salary_Insert
go
create proc UP_Salary_Insert
(
@maxsalary money output, --傳出引數,最高工資標準
@empname nvarchar(20) output, --傳出引數,工資最高的員工姓名
@empno nvarchar(10),
@salary money=10000,
@stime datetime
)
as
if(@stime<getdate())
begin
--自定義錯誤,以便執行時獲取詳細的錯誤資訊,錯誤級別15,狀態1為默認值
raiserror('新的工資標準執行日期必須大于當前日期',15,1)
return --退出存盤程序的執行
end
insert into salary values(@empno,@salary,@stime)
select @empname=empname,@maxsalary=maxsal.salary
from
(select top 1 empno,Sal.salary as salary from (select * from Salary where StartTime in (select MAX(StartTime) from Salary group by EmpNo)) as sal order by sal.Salary desc) as maxsal,
employee
where maxsal.empno=employee.empno
go
--執行存盤程序,捕獲錯誤
declare @maxsal money=0,@emp nvarchar(20)=''
exec UP_Salary_Insert @maxsal output,@emp output,'e011',8888888888,'2000-01-01'
declare @err int
set @err=@@ERROR
if(@err<>0)
begin
print '錯誤號:'+convert(varchar(10),@err)
return --退出批處理,后續陳述句將不再執行
end
print @emp
print '工資'+ convert(varchar(100),@maxsal)
go
--上機階段1
---------------------------創建和使用標量值函式,創建和使用多陳述句表值函式
/*
指導部分
訓練型別
創建標量值函式
將標量值函式作為列的默認值使用
創建多陳述句表值函式
需求說明
創建標量值函式,完成判斷‘游戲點卡銷售系統’中用戶注冊時間,當注冊時間處于每天的0點到7點是,贈送用戶50元購物卡金額,
在用戶表中添加默認值約束,將函式的回傳值作為新用戶余額的默認值

創建一個多陳述句白哦之函式,完成根據接受的年份回傳此用戶每月的消費金額

實作思路
在標量值函式中徐需要判定系統時間,根據時間回傳不同的值,如果時間在0點到7點之間,就回傳50元,否則回傳0.多陳述句表值函式內,
回傳一個包含用戶名,月份,月消費合計3個列的table型別的資料記錄
*/
--實作步驟
-- 1,無引數的表量值函式,回傳值為money型別
use cardsale
go
create function DefaultMoney()
returns money
as
begin
declare @money money=0
--0點到7點之間
if(datepart(hh,getdate())>=0 and datepart(hh,getdate())<=7)--如果當前時間是在0-7點之間,通過datepart()獲取當前時間的小時
set @money=50
return @money
end
go
--2,使用系統函式檢查函式是否創建成功
execute sp_helptext 'DefaultMoney'
go
--3,使用T-SQL 為UserInf表添加默認值約束
alter table userinf add constraint DF_Balance default(dbo.DefaultMoney()) for Balance
go
--4,呼叫系統存盤程序sp_helpconstraint查看USERINF表的約束,
exec sp_helpconstraint userinf
--5,將計算機系統時間調至0點到7點之間,輸入測驗資料,檢查函式是否能成功作為默認值使用
insert into UserInf
values('測驗001',123456,'程式員',1,'','','','',50,'2','1','')
--6,創建一個標值函式,函式接收一個datetime型別的引數,回傳含有3個欄位的table型別集合,
-- 查詢的時候線通過3張表連接查詢出所有用戶一年年的消費記錄,然后將該結果集作為子查詢,
-- 按用戶的月份進行分組合計
alter function getsalebymonth(@date datetime)
returns @sales table --回傳表值
(
username varchar(20),
smonth int,
amount money
)
as
begin
insert into @sales select uname,MONTH(stime),SUM(price)
from
(select s.UserName uname,s.ShopTime stime,ct.Price price
from ShopHistory s,CardInf ci, CardType ct
where s.CardNo=ci.CardNo and ci.CardTypeId=ct.Id and year(s.ShopTime)=year(@date)) SaleInf
group by uname,MONTH(stime)

return
end
--7,使用select測驗該表值函式
declare @date datetime='2016-8-27' --呼叫函式錢要先宣告變數
select * from getsalebymonth(@date)
/*
練習部分(一)
需求說明:創建一個無引數的存盤程序,呼叫階段1指導部分創建的標值函式,
實作如下業務規則:本年度消費金額滿500元的用戶,回傳購卡金額的10%到用戶賬戶
使用IN
*/
--使用函式進行查詢,查詢結果作為更新的條件
update userinf set Balance=Balance+500 where UserName in
(select distinct username from getsalebymonth(GETDATE())
where amount>=500)
/*
練習部分(二)
需要說明:使用系統存盤程序,將D盤中的兩個檔案1.TXT和2.TXT進行連接,生產一個新的檔案
使用xp.cmdshell
*/
exec sp_configure 'show advanced options',1
execute xp_cmdshell 'copy /b D:\1.txt + D:\2.txt D:\3.txt'
--上機階段2
---------------------------撰寫帶引數的存盤程序,使用系統存盤程序
/*
指導部分:
撰寫帶輸入和輸出的存盤程序
使用系統存盤程序將用戶自定義訊息寫入windows事件查看器
執行存盤程序

需求說明
1,創建存盤程序,實作管理員登錄功能
2,創建存盤程序,要求時間用戶購買游戲卡程序,如果用戶要購買的游戲卡的金額超過了用戶賬戶余額,則引發用戶自定義的錯誤,
并使用系統存盤程序將錯誤寫入到windows時間查看器,完成存盤程序,檢查windows事件查看器中寫入的錯誤資訊

實作思路
實作管理員登錄功能只需要傳入引數,即用戶名和密碼,實作用戶購買游戲卡存盤程序時,如果用戶的余額不足購買游戲卡,則使用
raiserror引發自定義的錯誤,在執行存盤程序后,使用xp_logevent擴展程序將用戶自定義的錯誤號寫入windows事件查看器中

實作步驟
1,創建存盤程序UP_Admin_Login
*/
use Company_DB
go
create proc UP_Admin_Login
(
@uname varchar(20), --輸入用戶名
@pwd varchar(20), --輸入密碼
@tag int output --傳出是否登錄成功的標志(1表示登錄成功 0表示登錄失敗)
)
as
set @tag=0
if((select COUNT(*) from UserInf where UserName=@uname and [password]=@pwd and UserRoleId=4)>0)
begin
set @tag=1
end

-- 2, 執行存盤程序
declare @flag int
exec UP_Admin_Login 'admin','admin123', @flag output
if(@flag=1)
print '管理登錄成功!'
else
print '身份驗證失敗,無法登錄!'
go

-- 3,輸入代碼,創建用戶購買游戲卡的存盤程序
if(exists (select * from sysobjects where name='UP_BuyCard'))
drop proc UP_BuyCard
go
-- 4,創建存盤程序,存盤程序一次購買一張卡,要求輸入卡型別,用戶名,
alter procedure UP_BuyCard
(
@CardtypeName nvarchar(50), --游戲卡名稱
@user varchar(20) --用戶名
)
as
declare @typeid int --卡型別變數
declare @sumerror int=0 --錯誤變數
declare @cnt int --次數變數
select @typeid=id from CardType where CardtypeName=@CardtypeName --根據用戶提供的游戲卡名稱查詢這個游戲的型別ID

select @cnt=COUNT(*) from CardInf where CardtypeId=@typeid --根據游戲的型別ID和游戲卡'未出售'ID查詢這個游戲卡的庫存剩余數量
and CardStateId=(select id from CardState where cstate='未售出')

if(@cnt>=1) --檢查是否有可以售出的卡
begin
declare @balance money,@requiremoney money--宣告變:剩余錢,需要錢
select @balance=balance from UserInf where UserName=@user --根據用戶提供的用戶名查找這個用戶的賬戶余額
select @requiremoney=price from CardType where Id=@typeid --根據游戲要購買的游戲卡的型別ID查詢這個游戲卡的價格
select @requiremoney=@requiremoney*(select discount from RoleInf --根據用戶提供的用戶名查詢這個用戶的身份ID,再根據身份ID查詢則扣率,最后根據則扣率*需要錢,從而查詢出這個用戶購買游戲卡需要花費的錢
where Id=(select UserRoleId from UserInf where UserName =@user))
begin
--開始購卡
begin transaction --開始事物
declare @cardno varchar(20)
--可以出售的某類游戲卡中帳號的一張
select @cardno=MAX(cardno) from CardInf where
CardtypeId=@typeid and CardStateId=(select id from CardState where cstate='未售出')--根據游戲卡型別和游戲狀態查找這類游戲的帳號,找出一張賦值給@cardno變數

insert into shoppingCart values(@user,(select id from CardType where CardtypeName=@CardtypeName),1)
set @sumerror+=@@error
update CardInf set CardStateId=2 where CardNo=@cardno--更新賣出去的這張卡號的狀態
set @sumerror+=@@error --給@sumerror賦值用于查看上一個增刪改操作是否出錯
update UserInf set balance -= @requiremoney where UserName=@user--跟新用戶的錢
set @sumerror+=@@error
if(@sumerror>0)
begin
print 'NO'
rollback transaction--回滾事物
end
else
begin
print 'OK'
commit transaction--提交事物
end
end
end
else
begin
--引發用戶自定義的錯誤
raiserror('賬戶的余額不夠,請及時充值!',16,1)
end
go



declare @err int
exec UP_BuyCard '英雄聯盟游戲卡','我有錢'
set @err=@@ERROR+150505050 --訊息日志中只能寫入訊息號大于50000的訊息
if(@err<>0)
--寫入錯誤資訊到windows訊息日志
execute xp_logevent @err, '賬戶余額不足,請及時充值',informational


--聯系部分

--需求說明
--使用存盤程序實作用戶匯款和用戶投訴功能,要求用戶匯款后立即審核,并將用戶的賬戶余額回傳,匯款銀行使用默認值‘工商銀行’,存盤程序撰寫完畢后,為用戶‘我有錢’匯款1000元
--實作思路
--用戶匯款后要求能夠通知用戶當前的賬戶余額,可以通過傳出引數實作,匯款銀行通過傳入引數添加默認值實作
go
alter procedure UP_Postmonry
(
@user nvarchar(20),
@money money,
@bank nvarchar(20)='工商銀行',
@desc nvarchar(1000),
@balance money output
)
as
begin
--匯款代碼-----------------------------------------------------
--1,判斷用戶的余額是否夠購買游戲卡
declare @err int
select @balance=Balance from UserInf where UserName=@user
if(@balance>=@money)
begin
begin transaction--開始事物
update UserInf set Balance=Balance+@money where UserName='admin'
set @err+=@@ERROR
update UserInf set Balance=Balance-@money where UserName=@user
set @err+=@@ERROR
if(@err > 0)
rollback transaction
else
begin
print '轉賬成功!'
commit transaction
end
end
else
begin
print '您的賬戶余額不足,請及時充值!匯款失敗!'
end

--審核代碼-----------------------------------------------------

--為傳出引數賦值----------------------------------------------
select @balance=Balance from UserInf where UserName='我有錢'
end
go
declare @amount money
--引數@bank沒有傳入具體值,引數使用默認值
execute UP_Postmonry @user='我有錢',@money=1000,@desc='購買天堂游戲卡',@balance=@amount output
print '用戶我有錢的余額是'+convert(nvarchar(20),@amount)
-----------------------------------------------------視頻資料-----------------------------------------------------------------------------------------------------------------------------------------
use PPTDemo
create table Tb_Student(
TId int identity(1,1) primary key,
TGender nvarchar(2),
TSalary money,
TAge int,
TBirthday datetime
)
-----------------------------------------
create table Employees
(
EmpId int identity(1,1),
EmpName varchar(50),
EmpGender char(2),
EmpAge int,
EmpEmail varchar(100),
EmpAddress varchar(500)
)
create table Department
(
DepId int identity(1,1),
DepName varchar(50)
)
select * from Employees
select * from Department
drop table Employees
---------------------------------------手動增加約束
--手動洗掉一列
alter table Employees drop column EmpAddress
--手動增加一列
alter table Employees add EmpAddress nvarchar(1000)
--修改一下EmpEmail的資料型別(varchar(200))
alter table Employees alter column EmpEmail varchar(200)
--為EmpId增加一個主鍵約束
alter table Employees add constraint PK_Employees_EmpId primary key(EmpID)
--非空約束,為EmpName增加一個非空約束(修改列)
alter table Employees alter column EmpName varchar(50) not null
--為EmpName增加一個唯一約束
alter table Employees add constraint UQ_EEmployees_EmpName unique(EmpName)
--為EmpGender增加一個默認約束,默認‘男’
alter table Employees add constraint DF_Employees_EmpGender default('男') for EmpGender
--為EmpGender增加一個檢查約束,要求只能是'男'or'女'
alter table Employees add constraint CK_Employees_EmpGender check(EmpGender='男' or EmpGender='女')
--為年齡增加一個檢查約束;年齡在0-120歲之間
alter table Employees add constraint CK_Employees_EmpAge check(EmpAge>=0 and EmpAge<=120)
--創建一個部門表,然后為Eemployee表增加一個DepId列
alter table Employees add Employees int
--為Department表設定主鍵,主鍵列是:DepId
alter table Department add constraint PK_Department_DepId primary key(DepId)
--增加外鍵約束
alter table Employees add constraint PK_Employees_Department foreign key(EmpDepId) references Department(DepId)
---------------------------------------------------------------------------------------------
-----洗掉約束(多個一起洗掉)-------------------------------------------------------------
alter table Employees drop constraint PK_Employees_EmpId,UQ_EEmployees_EmpName,CK_Employees_EmpAge,CK_Employees_EmpGender,DF_Employees_EmpGender
-----增加約束(多個一起增加)-------------------------------------------------------------
alter table Employees add
constraint CK_Employees_EmpAge check(EmpAge>=0 and EmpAge<=120),
constraint CK_Employees_EmpGender check(EmpGender='男' or EmpGender='女'),
constraint DF_Employees_EmpGender default('男') for EmpGender,
constraint UQ_Employees_EmpName unique(EmpName),
constraint PK_Employees_EmpId primary key(EmpID)
create table Employees
(
EmpId int identity(1,1) identity(1,1) primary key,
EmpName varchar(50) not null unique check(len(EmpName)>2),
EmpGender char(2) default('男'),
EmpAge int check(EmpAge>0 and EmpAge<120),
EmpEmail varchar(100) unique,
EmpAddress varchar(500) not null
EmpDepId int foreign key references Department(DepId) on delete cascade--on delete cascade級聯洗掉
)
--查詢所有行所有列
select * from Employees
--查詢所有行部分列
select EmpId,EmpName,EmpGender from Employees
--查詢部分行所有列(使用where條件篩選部分行顯示)
select * from Employees where EmpAge='20'
--給查詢結果集中的列起別名(只是把當前查詢出來的結果集的列名修改了,對原表沒有修改)
select EmpId as 員工編號,EmpName as 學生姓名,EmpGender as 學生性別 from Employees
select 員工編號=EmpId,學生姓名=EmpName,學生性別=EmpGender from Employees
--給查詢結果集中新增加列
select 員工編號=EmpId,學生姓名=EmpName,學生性別=EmpGender,婚否='' from Employees
/**SELECT不必和FROM配合使用,可以單獨使用
獲取系統當前系統時間
*/
select 當前系統時間=GETDATE()
select GETDATE() as 當前系統時間
select
打野='皇子',
中單='莫干娜',
ADC='女警',
輔助='風女'


------------------------------------------------TOP和DISTINCT---------------------------------
--去除重復失敗,因為有自增主鍵,所以原表資料沒有重讀
select distinct * from Employees
--DISTINCT關鍵字,針對已經查詢出的結果集進行去除重復
--此處的DISTINCT關鍵字的作用是針對select EmpName,EmpGender from Employees查詢結果集去重復,EmpName和EmpGender的值完全一樣,可以成功
select DISTINCT EmpName,EmpGender from Employees
--TOP獲取前幾條資料,TOP一般都與order by一起使用
--TOP
--查詢年齡最高的前5名
select top 5 * from Employees order by EmpAge desc
--如果TOP后面不是數字,而是一個運算式一定要使用()把運算式括起來
select top (5*20) * from Employees order by EmpAge desc
--查詢前分之分30
select top 30 percent * from Employees order by EmpAge desc
--order by 列名
--按照年齡,降序排序
select * from Employees order by EmpAge desc
--按照年齡, 升序排序
select * from Employees order by EmpAge asc--默認升序
------------------------------------------------聚合函式---------------------------------
--統計出所有人的年齡的總和
select SUM(EmpAge) as 年齡的綜合 from Employees
--統計出表中一共有多少條記錄
select COUNT(*) as 一共的記錄 from Employees
--統計出表中所有人的平均年齡(因為整數/整數=整數,為了讓結果成為小數,可以*0.1)
select
(select SUM(EmpAge) as 年齡的綜合 from Employees)*1.0/(select COUNT(*) as 一共的記錄 from Employees) as 平均年齡
from Employees

--年齡最大的
select MAX(EmpAge) from Employees
--年齡最小的
select MIN(EmpAge) from Employees
--計算平均值
select AVG(EmpAge*1.0) from Employees
----------------------------------------------------聚合函式的一些其它的問題------------------------
--1.聚合函式不統計空值
--2.如果使用聚合函式的時候,沒有手動group by分組,那么聚合函式會把整個表中的資料作為一組來統計
select *from Employees
select count(EmpEmail) from Employees

select AVG(EmpAge) from Employees--AVG()也不統計空值

-------------------------------帶條件查詢
--select 列
--from 表
--where 條件
--查詢沒有及格的學生(假設:數學或英語,只要有一門沒有及格就叫沒有及格)的學號
select tSId from TblScore where tEnglish<60 or tMath<60

--查詢年齡在20-30之間的男學生 AND
select * from MySudent where FAge>=20 and FAge <=30 and FGender='男'

--between...and 在....之間(閉區間,包含兩個端點值) BETWEEN
select * from MySudent where FAge between 20 and 30 and FGender='男'

--查詢出所有班級Id為3,4,5的那些學生 OR
select * from MySudent where classid=3 or classid=4 or classid=5
select * from MySudent where classid in(3,4,5)

--對于in或者or查詢,如果查詢中的條件是連續的幾個數字,最好使用>= <=或者between...and 不要使用or或者and
select * from MySudent where classid>=3 and classid<=5

-------------------------------模糊查詢
-- _ 表示任意的當個字符
-- % 表示任意多個任意的字符
-- []表示篩選,范圍



-------------------------------空值處理---------------------------------------------
--null值無法使用=或<>來進行比較

--查詢所有年齡是null的同學資訊
select * from MySudent where Age is null

--查詢所有年齡不是null的同學
select * from MySudent where Age is not null
--任何值與null進行運算,結果還是null
select 2000+null
-----------------------------------執行順序---------------------------------------------
select * --3.
from Score --1.
where english>60 and math>60 --2.
order by english desc,math desc --4.
--------------------------------------GROUP BY---------------------------------------------重點!!!
/*
在使用select查詢的時候,又是需要對資料進行分組匯總(即:將現在有的資料按照某列來匯總統計),這時候就用到GROUP BY陳述句,
select陳述句中可以使用group by字句將行劃分成較小的組,然后,使用聚合函式回傳每一個組的匯總資訊,
分組一般都和聚合函式連用
*/
create table studenttest
(
xh int not null,
xm varchar(10) not null,
xb varchar(2) not null,
km varchar(10) not null,
cj int
)
drop table studenttest
insert into studenttest values(1,'韓曉青','女','C語言',55);
insert into studenttest values(2,'洪少俠','男','C語言',56);
insert into studenttest values(3,'胡友松','男','C語言',57);
insert into studenttest values(4,'蒯衛','女','C語言',58);
insert into studenttest values(5,'雷雨慧','男','C語言',59);
insert into studenttest values(6,'李歡歡','女','C語言',60);
insert into studenttest values(7,'李文杰','男','C語言',61);
insert into studenttest values(8,'劉梅','女','C語言',62);
insert into studenttest values(9,'路俊鵬','男','C語言',63);
insert into studenttest values(10,'呂鋼','男','C語言',64);
insert into studenttest values(11,'潘桂琴','女','C語言',65);
insert into studenttest values(12,'錢歡','男','C語言',66);
insert into studenttest values(13,'邵旭','男','C語言',67);
insert into studenttest values(14,'水玉帥','男','C語言',68);
insert into studenttest values(15,'宋元芬','女','C語言',69);
insert into studenttest values(16,'王斌','男','C語言',70);
insert into studenttest values(17,'聞雪','女','C語言',71);
insert into studenttest values(18,'向瑤','女','C語言',72);
insert into studenttest values(19,'謝守鵬','男','C語言',73);
insert into studenttest values(20,'楊麗敏','女','C語言',74);
insert into studenttest values(21,'楊文財','男','C語言',75);
insert into studenttest values(22,'張紅','女','C語言',76);
insert into studenttest values(23,'張明婷','女','C語言',77);
insert into studenttest values(24,'張鵬宇','男','C語言',78);
insert into studenttest values(25,'張帥','男','C語言',79);
insert into studenttest values(1,'韓曉青','女','JAVA語言',22);
insert into studenttest values(2,'洪少俠','男','JAVA語言',23);
insert into studenttest values(3,'胡友松','男','JAVA語言',24);
insert into studenttest values(4,'蒯衛','女','JAVA語言',25);
insert into studenttest values(5,'雷雨慧','男','JAVA語言',26);
insert into studenttest values(6,'李歡歡','女','JAVA語言',27);
insert into studenttest values(7,'李文杰','男','JAVA語言',28);
insert into studenttest values(8,'劉梅','女','JAVA語言',29);
insert into studenttest values(9,'路俊鵬','男','JAVA語言',30);
insert into studenttest values(10,'呂鋼','男','JAVA語言',31);
insert into studenttest values(11,'潘桂琴','女','JAVA語言',32);
insert into studenttest values(12,'錢歡','男','JAVA語言',33);
insert into studenttest values(13,'邵旭','男','JAVA語言',34);
insert into studenttest values(14,'水玉帥','男','JAVA語言',35);
insert into studenttest values(15,'宋元芬','女','JAVA語言',36);
insert into studenttest values(16,'王斌','男','JAVA語言',37);
insert into studenttest values(17,'聞雪','女','JAVA語言',38);
insert into studenttest values(18,'向瑤','女','JAVA語言',39);
insert into studenttest values(19,'謝守鵬','男','JAVA語言',40);
insert into studenttest values(20,'楊麗敏','女','JAVA語言',41);
insert into studenttest values(21,'楊文財','男','JAVA語言',42);
insert into studenttest values(22,'張紅','女','JAVA語言',43);
insert into studenttest values(23,'張明婷','女','JAVA語言',44);
insert into studenttest values(24,'張鵬宇','男','JAVA語言',45);
insert into studenttest values(25,'張帥','男','JAVA語言',46);
insert into studenttest values(26,'趙恒橋','男','JAVA語言',47);
insert into studenttest values(27,'趙鵬','男','JAVA語言',48);
insert into studenttest values(28,'周亞坤','男','JAVA語言',49);
insert into studenttest values(29,'鄒瑜','男','JAVA語言',50);
insert into studenttest values(30,'左云','女','JAVA語言',51);
insert into studenttest values(31,'大神','女','JAVA語言',51);
insert into studenttest values(1,'韓曉青','女','HTML',52);
insert into studenttest values(2,'洪少俠','男','HTML',53);
insert into studenttest values(3,'胡友松','男','HTML',54);
insert into studenttest values(4,'蒯衛','女','HTML',55);
insert into studenttest values(5,'雷雨慧','男','HTML',56);
insert into studenttest values(6,'李歡歡','女','HTML',57);
insert into studenttest values(7,'李文杰','男','HTML',58);
insert into studenttest values(8,'劉梅','女','HTML',59);
insert into studenttest values(9,'路俊鵬','男','HTML',60);
insert into studenttest values(10,'呂鋼','男','HTML',61);
insert into studenttest values(11,'潘桂琴','女','HTML',62);
insert into studenttest values(12,'錢歡','男','HTML',63);
insert into studenttest values(13,'邵旭','男','HTML',64);
insert into studenttest values(14,'水玉帥','男','HTML',65);
insert into studenttest values(15,'宋元芬','女','HTML',66);
insert into studenttest values(16,'王斌','男','HTML',67);
insert into studenttest values(17,'聞雪','女','HTML',68);
insert into studenttest values(18,'向瑤','女','HTML',69);
insert into studenttest values(19,'謝守鵬','男','HTML',70);
insert into studenttest values(20,'楊麗敏','女','HTML',71);
insert into studenttest values(21,'楊文財','男','HTML',72);
insert into studenttest values(22,'張紅','女','HTML',73);
insert into studenttest values(23,'張明婷','女','HTML',74);
insert into studenttest values(24,'張鵬宇','男','HTML',75);
insert into studenttest values(25,'張帥','男','HTML',76);
insert into studenttest values(26,'趙恒橋','男','HTML',77);
insert into studenttest values(27,'趙鵬','男','HTML',78);
insert into studenttest values(28,'周亞坤','男','HTML',79);
insert into studenttest values(29,'鄒瑜','男','HTML',80);
insert into studenttest values(30,'左云','女','HTML',81);
insert into studenttest values(31,'哈哈','女','HTML',81);
insert into studenttest values(32,'王云','女','HTML',81);
insert into studenttest values(33,'旺財','女','HTML',81);
select * from studenttest
--查詢每個科目的人數
select km,max(xh) as 科目人數 from studenttest group by km
--統計性別人數
select 性別=xb,COUNT(xb) from studenttest group by xb
--統計每個科目男同學的人數,和男同學的平均分
select km,COUNT(*) as 男同學人數,avg(cj) 平均成績 --4
from studenttest --1
where xb='男' --2
group by km --3
--當使用了分組陳述句(group by)或者是聚合函式的時候,在select的查詢串列中不能再包含其他列名,
-- 除了該列同時也出現了group by字句中,或者該列也包含了在某個聚合函式中
-------------------------------HAVING與where-----------------------------
--對分組以后的資料進行篩選:使用having
--對分組以前的資料進行篩選:使用where
select km,COUNT(*) as 男同學人數,avg(cj) 平均成績 --4
from studenttest --1
group by km --2
having avg(cj)>60 --3 -- 因為先執行的having后執行的select所以不可以使用別名,再它之前別名還沒有創建
-- order by可以使用別名,因為order by永遠是最后執行,再它之前別名已經創建好了

---------------------------------型別轉換函式CAST,CONVERT
select '1000'+100
print '1000'+100
select 100.0+'1000'--失敗,將 varchar 轉換為資料型別 numeric 時出現算術溢位錯誤,
select 100.0+CAST('1000' as int)
select 100.0+CONVERT(int,'1000')
select '你的班級編號是:'+1--在將 varchar 值 '你的班級編號是:' 轉換成資料型別 int 時失敗,
select '你的班級編號是:'+CONVERT(nvarchar(1),1)
--TableConvert表中bid列是varchar型別的數字,要求按數字大小排序,需要轉換型別
select * from TableConvert order by CONVERT(int,bid) desc
--轉換時間格式
print convert(varchar(100),getdate(),120)
print convert(varchar(10),getdate(),120)
---------------------------------UNION聯合結果集(集合運算子)---------------------------------
--聯合:指把結果集的行聯合起來 5行+4行 結果集9行
--連接:指吧結果集的列連接起來 3列+4列 結果集7列
select * from TBStudent
union all
select * from MyStudent--聯合不了,因為列數不同,資料型別不兼容
----------------UNION進行聯合,區別在于:使用union聯合會去除重復,從新排列
----------------UNION ON進行聯合,區別在于:不會去除重復也不會從新排列
----------------大多數情況下,聯合的時候不需要去除重復,同時要保持資料的順序,所以一般建議使用 UNION ALL
select tname,tgender,tage from TBStudent
union all
select tname,tgender,tage from MyStudent--可以聯合,列數相同,資料型別兼容(不會去除重復也不會從新排列)
select tname,tgender,tage from TBStudent
union
select tname,tgender,tage from MyStudent--可以聯合,列數相同,資料型別兼容(使用union聯合會去除重復,從新排列)
--查詢出成績表中的:最高分,最低分,平均分
select
MAX(cj) as 最高分,
min(cj) as 最低分,
avg(cj) as 平均分
from studenttest
select
最高分=(select MAX(cj) from studenttest),
低分分=(select MIN(cj) from studenttest),
平均分=(select AVG(cj) from studenttest)
select 名稱='最高分',分數=MAX(cj) from studenttest
union all
select 名稱='最低分',分數=MIN(cj) from studenttest
union all
select 名稱='平均分',分數=avg(cj) from studenttest
-----------------使用UNION一次插入多行資料
SELECT * FROM studenttest
INSERT into studenttest
select '37','大王','男','修仙','500' union all
select '37','觀音','女','修仙','600' union all
select '37','豬八戒','男','修仙','700' union all
select '37','悟空','男','修仙','800'
--在使用union進行插入資料的時候也要注意union會去除重復的,
--下面union插入只會插入4條資料,建議使用union all
INSERT into studenttest
select '37','大王','男','修仙','500' union
select '37','觀音','女','修仙','600' union
select '37','豬八戒','男','修仙','700' union
select '37','悟空','男','修仙','800'union
select '37','大王','男','修仙','500' union
select '37','觀音','女','修仙','600' union
select '37','豬八戒','男','修仙','700' union
select '37','悟空','男','修仙','800'
---------------------------------------向表中插入多條記錄------------------------------
--查詢所有表中所有的資料保存到另外一張表中
--用于備份表
--意思是從studenttest表中查詢資料保存到tempstustudenttest這張表中,如果預先沒有tempstustudenttest這張表,
--當執行insert into陳述句的時候會自動創建tempstustudenttest表,
--tempstustudenttest表結構和studenttest表結構和自動偏好列一樣,但是tempstustudenttest表中沒有studenttest表中的約束
--insert into陳述句不能夠重復執行,因為每次執行都會創建一個tempstustudenttest表
--student
select * into tempstustudenttest from studenttest
--select * from tempstustudenttest
--select * from studenttest
drop table tempstustudenttest
--用于拷貝表結構,不拷貝資料
select * into tempstustudenttest from studenttest where 1<>1
select top 0 * into tempstustudenttest from studenttest
select * from tempstustudenttest
--使用insert into 表 select,,,from 表
--把studenttest表中的資料添加到已有資料的tempstustudenttest表中
select * from tempstustudenttest
insert into tempstustudenttest values(50,'大黃蜂','男','機械化',120);
insert into tempstustudenttest values(55,'機械公敵','男','科技化',250);
insert into tempstustudenttest
select * from studenttest where xb='女'
---------------------------------------常用的字串函式------------------------------
--1.len() 計算字符的個數
print len('我愛你520')
--datalength()回傳所占用的位元組的個數,這個不是字串函式
print datalength('我愛你520')--9
print datalength(N'我愛你520')--12
--2.
print upper('hello world') --轉換大寫
print lower('HELLO WORLD') --轉換小寫
--3.去掉兩段的空格
print '========='+' hello '+' =============='
print '========='+ltrim(' hello ')+' =============='--去掉左邊空格
print '========='+rtrim(' hello ')+' =============='--去掉右邊空格
print '========='+rtrim(ltrim(' hello '))+' =============='--去掉兩段的空格
--4.字串的截取
--4.1 left()
print left('大野太菜了!!!',5)--大野太菜了
--4.2 right()
print right('大野太菜了!!!',3)--!!!
--4.3 substring()截取字串
print substring('大野太菜了!!!',3,3)--太菜了
print substring('大野太菜了!!!',-2,5)--
------------------------------------------日期函式------------------------------------------
print getdate()
print sysdatetime()
print dateadd()--增加時間
select dateadd(day,200,getdate())
select dateadd(month,200,getdate())
select dateadd(year,200,getdate())
select dateadd(minute,200,getdate())
select dateadd(second,200,getdate())
select dateadd(hour,200,getdate())
--查詢入學大于一年的學生,用DATEADD()
select * from studenttest
where DATEADD(DAY,365,jointime)<=GETDATE()
--計算兩個時間的差
select DATEDIFF(YEAR,'1991-5-31',GETDATE())
--查詢出入職N年的人的個數
select 入職時間=DATEDIFF(YEAR,jointime,GETDATE()),人數=COUNT(*) from studenttest group by DATEDIFF(YEAR,jointime,GETDATE())
--獲取日期的某部分的值@return int
print datepart(year,getdate())
print year(getdate())
print datepart(month,getdate())
print month(getdate())
print datepart(day,getdate())
print day(getdate())
--回傳日志的某部分值@return string
print datename(year,getdate())
--查詢出,不同年份入職的員工的個數
select
入學日期=YEAR(jointime),
COUNT(*)
from studenttest
group by jointime
-------------------------------題目
create table tonghua(
id int identity(1,1) primary key,
CellNumber varchar(20),
TelNum varchar(20),
StartDateTime datetime,
EndDateTime datetime
)
drop table tonghua
select * from tonghua
insert into tonghua
select '001','02088888','2010-07-10 10:00:00','2010-07-10 10:05:03' union all
select '001','02088888','2010-07-11 13:00:00','2010-07-11 13:01:10' union all
select '001','89898989','2010-07-11 14:06:00','2010-07-11 14:09:00' union all
select '002','98987676','2010-07-13 21:06:00','2010-07-13 21:08:08' union all
select '002','02188839389','2010-06-29 20:11:00','2010-06-29 20:16:06' union all
select '001','767676766','2010-07-15 13:16:00','2010-07-15 13:26:00' union all
select '003','0227864656','2010-07-13 11:16:00','2010-07-13 11:17:09' union all
select '003','676765777','2010-07-19 19:26:02','2010-07-19 19:30:33' union all
select '001','89977653','2010-06-19 15:16:02','2010-06-19 15:26:10' union all
select '004','400400400','2010-06-19 23:40:02','2010-06-20 10:10:00'
--輸出所有資料中通話時間最長的5條記錄,
select top 5 *,通話時長=datediff(second,startdatetime,enddatetime)
from tonghua
order by 通話時長 desc
--輸出所有資料中撥打長途號碼(對方號碼以0開頭)的總時長.
select * ,通話時間=DATEDIFF(SECOND,startdatetime,enddatetime)
from tonghua
where telnum like '0%'
--假設今天是'2010-07-31'
--輸出本月通話時間總時長最多的前三個呼叫員的編號
select top 3
cellnumber,
通話時長=sum(datediff(second,startdatetime,enddatetime))
from tonghua
where DATEDIFF(MONTH,startdatetime,'2010-07-31 00:00:00')=0--表示是本月
group by cellnumber
order by 通話時長 desc
--輸出本月撥打電話次數最多的前三額呼叫元的編號
select
top 3
cellnumber,
撥打電話次數=COUNT (*)
from tonghua
where DATEDIFF(MONTH,startdatetime,'2010-07-31 00:00:00')=0
group by cellnumber
order by 撥打電話次數 desc
----------------------------------------------第一階段結束-------------------------------------------------------
------------------------------------------------內連接--------------------------------------------------------
create table PhoneType
(
ptId int identity(1,1) primary key,
ptName nvarchar(20)
)
create table PhoneNum
(
pId int identity(1,1) primary key,
pTypeId int,
pName nvarchar(20),
pCellPhone varchar(20),
pHomePhone varchar(20)
)
drop table PhoneType
drop table PhoneNum
insert into PhoneNum
select '1','劉備','13000000000','7000000' union all
select '1','關羽','13000000001','7000001' union all
select '1','張飛','13000000002','7000002' union all
select '2','曹操','13000000003','7000003' union all
select '2','大喬','13000000004','7000004' union all
select '3','孫權','13000000003','7000003' union all
select '3','小喬','13000000004','7000004'
insert into PhoneType
select '朋友' union all
select '同事' union all
select '同學' union all
select '家人'
select * from PhoneType
select * from PhoneNum
select * from PhoneType,PhoneNum --笛卡爾積
select *
from PhoneNum inner join PhoneType on PhoneNum.pTypeId=PhoneType.ptId --7條
select *
from PhoneNum inner join PhoneType on PhoneNum.pTypeId<>PhoneType.ptId --21條
--查詢的時候,如果表中有重名的列,此時,應該在通過 表名.列名 的方式來限定指定哪張表中的
select
pn.pid,
pn.pname,
pn.pcellphone,
pt.ptname
FROM PhoneNum as pn inner join PhoneType as pt on pn.pTypeId=pt.ptId
------------------------------------------------CASE多分支陳述句--------------------------------------------------------
create table [user](
[uid] int identity(1,1) primary key,
name nvarchar(20),
[level] int,
)
insert into [user]
select '犀利哥','1' union
select '小月月','2' union
select '芙蓉姐姐','3'
select * from [user]
------相當于if-else
select
*,
頭銜=case
when [level]=1 then '菜鳥'
when [level]=2 then '老鳥'
when [level]=3 then '大師'
else '骨灰級大師'
end
from [user]
------相當于switch
select
*,
頭銜=case [level]
when 1 then '菜鳥'
when 2 then '老鳥'
when 3 then '大師'
else '骨灰級大師'
end
from [user]
select * from studenttest
select
*,
等級=case
when cj>90 then '優秀'
when cj>80 then '良好'
when cj>70 then '中等'
when cj>59 then '及格'
when cj>0 then '不及格'
else '沒有參加考試'
end
from studenttest
--當A列大于B列時候選擇A,當B列大于C列的時候選擇c
create table ABC(
a int,
b int,
c int
)
insert into ABC
select '10','20','30' union
select '20','30','10' union
select '30','20','20' union
select '10','20','30'
select * from ABC
select 新A=case
when a>b then a
else b
end,
新B=case
when b>c then b
else c
end
from abc
-------------------
create table qiudui
(
scoreId int identity(1,1) primary key,
teamName nvarchar(20),
gameDate datetime,
gameResult nvarchar(20)
)
insert into qiudui
select '公牛','2012-05-01','勝' union
select '小牛','2012-06-01','勝' union
select '奇才','2012-05-15','負' union
select '湖人','2012-07-10','勝' union
select '公牛','2012-06-02','勝' union
select '公牛','2012-07-09','勝' union
select '奇才','2012-03-12','負' union
select '公牛','2012-09-11','負'
select * from qiudui
-----第一步
select
球隊名稱=teamname,
勝=case
when gameResult='勝' then 1
else 0
end,
負=case
when gameResult='負' then 1
else 0
end
from qiudui
-------第二步,第一步和第二步一起執行看看就懂了
select
球隊名稱=teamname,
勝=sum(case
when gameResult='勝' then 1
else 0
end),
負=sum(case
when gameResult='負' then 1
else 0
end)
from qiudui
group by teamname
-------上面題目使用count實作
select
球隊名稱=teamname,
勝=count(case
when gameResult='勝' then '勝'
else null
end),
負=count(case
when gameResult='負' then '負'
else null
end)
from qiudui
group by teamname
-------------------
create table StudentScroe(
aotuid int identity(1,1),
studentid int,
coursename nvarchar(20),
score int
)
drop table StudentScroe
insert into StudentScroe
select '001','語文','90' union all
select '001','數學','99' union all
select '001','英語','95' union all
select '002','語文','80' union all
select '002','數學','89' union all
select '002','英語','91' union all
select '003','語文','86' union all
select '003','數學','92' union all
select '003','英語','77'
-----第一步
select * from StudentScroe
select studentid,
語文=case
when coursename='語文' then score
else null
end,
數學=case
when coursename='數學' then score
else null
end,
英語=case
when coursename='英語' then score
else null
end
from StudentScroe
-----第二步
select studentid,
語文=max(case
when coursename='語文' then score
else null
end),
數學=max(case
when coursename='數學' then score
else null
end),
英語=max(case
when coursename='英語' then score
else null
end)
from StudentScroe
group by studentid
-------------------------------------------索引---------------------------------------------
--1.索引的目的,提高查詢效率
--2.索引分兩種
--2.1聚集索引(物理),一個表中只能有一個聚集索引
--2.2非聚集索引(邏輯),一個表中可以有多個聚集索引
--3.增加索引后,會增加額外的存盤空間,同時降低了增加新紀錄,修改,洗掉的效率
--創建非聚集索引
create nonclustered index 索引名稱 on [column]--列
--創建唯一非聚集索引
create unique nonclustered 索引名稱 index [column]--列
--創建聚集索引
create clustered index 索引名稱 on [column]--列
--洗掉索引
drop index [column]--列
-------------------------------------------子查詢---------------------------------------------
/*子查詢:把一個查詢的結果在另外一個查詢中使用叫子查詢
子查詢的基本分類
1.獨立子查詢:
子查詢可以獨立運行
2.相關子查詢
子查詢中參考了父查詢中的結果

*/
---------------------------------------分頁查詢---------------------------------------
---------------------------------------使用TOP分頁
--要分頁查詢,或者分頁顯示,首先要確定按照上面排序,然后才能確定哪些記錄該在第一頁,哪些記錄該在應該在第二頁
--第一頁顯示7條資料
--第1頁
select top 7 * from studenttest order by xh asc
--查詢前兩頁的資料
select top (7*2) * from studenttest order by xh asc
--第2頁
--2.1先查詢出(2-1)頁的資料的xh
select top 7 * from studenttest where xh not in
(select top 7 xh from studenttest order by xh asc)
order by xh
---------------------------------------使用row_number()實作分頁
--1.為資料排序人,然后編號,
select *,Rn=row_number() over(order by xh asc) from studenttest
--2.根據用戶要查看的每頁記錄條數,以及要查看第幾頁,確定應該查詢第幾條到第幾條
--每頁顯示7條,要查看第4頁
--從3*7+1.....4*7
select *
from(select *,Rn=row_number() over(order by xh asc) from studenttest) as t
where t.Rn between 3*7+1 and 4*7
---------------------------------------連接查詢---------------------------------------
--內連接:值顯示那些兩張表中可以匹配的資料
--左外連接:坐標為主,左表的資料全部顯示,左右表匹配的資料顯示在右表,不匹配的資料顯示NULL
-----------------------------------事務,索引,視圖,同義詞
/*
1.事務的概念
事務時一種機制,它包含了一組資料庫操作命令,而且將所有的命名作為一個整體一起向資料庫提交或撤銷,這組命令要么都執行,要么都不執行,所以事務時一個不可分割的邏輯作業單元
2.事務的特點
雖然事務的每個執行單元都不相同,但所有的事物都具有4個特征,原子性,一致性,隔離性,持久性,簡稱ACID
3.事務的隔離級別
事務的4個特征中,隔離性用來解決多用戶操作中的并發沖突問題,
隔離級別:
未提交讀(read uncommitted)
已提交讀(read committed)
重復讀 (repeatable read)
可串行化(serializable)

未提交讀:事務之間最低的隔離級別,改級別只能保證不會讀取損壞的資料,即事務之間沒有什么隔離,事務能夠讀取其他食物正在修改并未提交的資料,這種隔離的級別無法確保資料的正確性

已提交讀:SQL SERVER 默認的隔離級別,改隔離級別能保證其他事務不能讀取當前事務正在修改但未提交的記錄,

重復讀: 這中隔離級別比較高,能確保其他事務不能修改當前事務中正在讀取但未提交的資料

可串行化:最高的隔離級別,事務之間完全隔離,事務之間按串行的方式執行,所以在這種級別的隔離下不存在并行化的操作,要訪問其他事務操作的資料,一定要等其他食物完全完成提交以后才能進行


*/
----------------------------------視圖
--視圖是虛擬表,只能存查詢陳述句,
--特點:安全,簡化操作
--create view viewname as <select 陳述句>
--視圖的查詢陳述句不要order by排序
------------------------------開始事務
begin transaction
declare @sum int=0
--在轉賬之前最好通過if-else判斷,不要讓程式發生例外報錯
update bank set balance=balance-1 where name='你好'
set @sum=@sum+@@error
update bank set balance=balance+1 where name='胡偉'
set @sum=@sum+@@error
--只要有一條sql執行出錯,那么最后的@sum就不是0
if @sum<>0
begin
--表示出錯了
--回滾
rollback
end
else
begin
--如果沒有出錯,則提交該事務
commit
end
--自動提交事務
--當執行一條sql陳述句的時候,資料庫自動幫我們打開一個事務,當陳述句執行成功,資料庫自動提交事務,執行失敗,資料庫自動回滾事務
--隱式事務
--每次執行一條sql陳述句的時候,資料庫自動幫我們打開一個事務,但是需要我們手動提交事務,或者回滾事務
set IMPLICIT_TRANSACTIONS on
set IMPLICIT_TRANSACTIONS off
INSERT INTO BANK VALUES ('有錢人','888888')
SELECT * FROM bank
commit
--顯示事務:需要手動打開事務,手動提交事務或者回滾事務
begin tran
commit tran
rollback tran
-------------------存盤程序
create proc usp_helloworld
as
begin
print 'hello world'
end
exec usp_helloworld
create proc usp_selectEmployee
as
begin
select * from Employee
end
exec usp_selectEmployee
--修改存盤程序
alter proc usp_selectEmployee
as
begin
select * from Employee where DeptNo='d01'
end
exec usp_selectEmployee
--創建一個帶兩個引數的存盤程序
create proc usp_add_number
@n1 int,
@n2 int
as
begin
select @n1+@n2
end
exec usp_add_number 100,500
--
use DB_Teacher
create proc usp_DB_Teacher
@gender char(2),
@studentaddress char(20)
as
begin
select * from student where studentsex=@gender and studentaddress=@studentaddress
end
exec usp_DB_Teacher '男','湖北襄樊'
--設定存盤程序的引數的默認值
--設定引數的默認值以后,呼叫存盤程序的時候要明確實參賦值的形參物件
create proc usp_add_number1
@n1 int,
@n2 int=50
as
begin
select @n1+@n2
end
exec usp_add_number1 100
create proc usp_add_number2
@n1 int=80,
@n2 int
as
begin
select @n1+@n2
end
exec usp_add_number2 @n2=100
---------------------------------------帶輸出引數的存盤程序
--當在存盤程序當中需要回傳多個值的時候,就可以使用輸出引數來回傳這些值,
use DB_Teacher
go
create proc usp_show_student
@gender char(2),
@count int output --輸出引數
as
begin
select * from student where studentsex=@gender
--把查詢陳述句查詢到的記錄條數賦值給變數@count
set @count=(select COUNT(*) from student where studentsex=@gender)
end
--呼叫存盤程序
--呼叫帶有輸出引數的存盤程序的時候,需要定義變數,將變數傳遞給輸出引數,
-- 在存盤程序中使用的輸出引數,其實就是你傳遞進來的變數,
declare @count int
exec usp_show_student @gender='男',@count=@count output
print @count
-------------使用存盤程序撰寫分頁查詢-------------
use PPTDemo
go
select * from studenttest
go
alter procedure usp_fenye
@pagesize int=7, --每頁記錄條數
@pageindex int=1, --當前要查看第幾頁記錄
@recordcount int output, --總的記錄條數
@pagecount int output --總的頁數
as
begin
--1,撰寫查詢陳述句,要把用戶的資料查詢出來
select
t.xh,
t.xm,
t.xb,
t.km,
t.jointime

from(select *,rn=ROW_NUMBER() over(order by xh asc) from studenttest ) as t
where t.rn between (@pageindex-1)*@pagesize+1 and @pageindex*@pagesize

--2,計算總的記錄條數
set @recordcount=(select COUNT(*) from studenttest)

--3,計算總的頁數
set @pagecount=ceiling(@recordcount*1.0/@pagesize)
end
--執行存盤程序
declare @i int,@j int
exec usp_fenye @recordcount=@i output,@pagecount=@j output
print '所有資料'+convert(varchar(10),@i)
print '頁數'+convert(varchar(10),@j)
------------------------------ 通過set賦值,與select賦值的區別
use PPTDemo
go
declare @a int
--set @a=(select COUNT(*) from studenttest) --set賦值
select @a=COUNT(*) from studenttest --select賦值
print @a
set @a=1
select @a=1
--當通過set為變數賦值的時候,如果查詢陳述句回傳的不止一個值的時候直接報錯
--但是,當通過select變數賦值的時候,如果查詢陳述句回傳的不止一個值的時候,那么會將最后一個結果賦值給該變數
------------------------------------觸發器
use Company_DB
create table HongFengHai(
studentid int,
studentname nvarchar(20),
studentgender nvarchar(2),
studentclass nvarchar(20)
)
select * from HongFengHai
select top 0 * into 測驗觸發器 from HongFengHai
go
--創建一個觸發器
create trigger trigger_delete_HongFengHai
on HongFengHai
after delete
as
begin
insert into 測驗觸發器 select * from deleted
end
delete from HongFengHai where studentclass='c語言'
————————————————
著作權宣告:本文為CSDN博主「藍蓮花Demo」的原創文章,遵循 CC 4.0 BY-SA 著作權協議,轉載請附上原文出處鏈接及本宣告,
原文鏈接:https://blog.csdn.net/qq84000508/article/details/53470070

------------恢復內容結束------------


-
-----------------------------------------------------SQL陳述句的執行順序------------------------------------------------------------------------

1>From 表
2>where 條件
3>group by 列
4>Having 篩選條件
5>select 5-1>被分組列,聚合函式列5-2>distinct>5-3>top
6>order by 列

-----------------------------------------------------GROUP BY---------------------------------------------------------------------------------

--當使用了分組陳述句(group by)或者是聚合函式的時候,在select的查詢串列中不能再包含其他列名,
-- 除了該列同時也出現了group by字句中,或者該列也包含了在某個聚合函式中
分組查詢語法: SELECT 被分組列, 聚合函式列 FROM 表名 WHERE 普通列 GROUP BY 被分組列 HAVING 被分組列, 聚合函式列 ORDER BY 被分組列, 聚合函式列

----------------------------------------------------------------------------------------------------------------------------------------------

update 表 set 列 (select 列 from 表)--子查詢
delete from 表名 where....----delete陳述句如果不加where條件,表示將表中所有的資料洗掉,加上where條件后,會按照where條件進行洗掉對應的行
insert into 表名(列1,列2,列3) values(值1,值2,值3)

------------------------------------------------建表約束----------------------------------------------------------

create table Employees
(
EmpId int identity(1,1) primary key,
EmpName varchar(50) not null unique check(len(EmpName)>2),
EmpGender char(2) default('男'),
EmpAge int check(EmpAge>0 and EmpAge<120),
EmpEmail varchar(100) unique,
EmpAddress varchar(500) not null
EmpDepId int foreign key references Department(DepId) on delete cascade--on delete cascade級聯洗掉
)
--------------------------------------------------------------------------------------------------------------------------------------
Connection 負責用來連接資料庫
ResultSet 結果集
PreparedStatement 負責用來執行sql陳述句
要用statement類的executeQuery()方法來下達select指令以查詢資料庫
executeQuery()方法會把資料庫回應的查詢結果存放在ResultSet類物件中供我們使用

第一步:加載驅動程式 Class.forName(DRIVER);
第二步:連接資料庫 Connection conn = DriverManager.getConnection(URL, "sa", "123456");
第三步:發送sql陳述句(增刪改) PreparedStatement pst = conn.prepareStatement(sql);
第四步:執行查詢
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("studentName")+"|"+rs.getString("studentAge"));
}

備份資料庫
backup database 資料庫名稱 to disk='路徑'
恢復資料庫
restore detabase 資料庫名稱 from disk='備份路徑'


SQL server中的常用資料型別

1.數字資料型別
整數型
bigint =long
int =int
smallint =shotr
tinyint =byte 0-255
bit 1~0

小數型
decimal
numeric 兩個一樣

貨幣型
money

2.字串型別
char
nchar
varchar
nvarchar
text
ntext
varchar(max)
nvarchar(max)

3.時間型別
datetime

4.二進制
binary 固定長度
vninary 可變長度

-------------------------------------------------------
帶n的和不帶n的區別
char(2) 表示可以儲存兩個位元組,ab,12,胡(英文,數字1個位元組,中文2個位元組)

nchar(2) 表示無論存盤中文還是英文,數字,每個字符都占用兩個位元組,ab,12,胡偉(英文,數字2個位元組,中文2個位元組)

不帶n的這些資料型別,長度最長可以設定為8000,
帶n的這些資料型別,長度最長可以設定為4000

char(8000)
varchar(8000)

nchar(4000)
nvarchar(4000)
-------------------------------------------------------
帶var的和不帶var的區別
nchar 不帶var表示,固定長度
varchar 帶var表示,可變長度

//固定長度,存盤1字符也是要占用10個位元組的,會自動補9個空格
char(10) 1 10位元組
1111111111 10位元組

//可變長度,會根據實際儲存資料的大小動態重新分配存盤空間,相對來說節省存盤空間
varchar(10) 1 1位元組
11111 5位元組

//10,表示最多10個位元組,如果存盤的資料超過了10個位元組,那么無論是固定長度還是可變長度都會報錯的,
-------------------------------------------------------
text 淘汰了,等于varchar(max)
ntext 淘汰了,等于nvarchar(max)

varchar(max) max表示4G
nvarchar(max) max表示4G

-------------------------------------------------------資料庫檔案
資料檔案 主要資料檔案 有且只有一個 .mdf(primary data file 的縮寫)
次要資料檔案 0或者多個 .ndf(primary data file 的縮寫)
日志檔案 無 至少一個 .ldf(log data file 的縮寫)

1. 字串函式:
CHARINDEX CHARINDEX('ab', 'cdab') 回傳 3 回傳'ab'在'cdab'中的位置,
SUBSTRING SUBSTRING('abc', 2, 2) 回傳 'bc' 從第2個位置開始截取長度為2的字串
LEN LEN('1個逗逼') 回傳 4 回傳字串的長度(非位元組長度)
UPPER/LOWER UPPER('aBc')/LOWER('aBc') 回傳'ABC'/'abc' 將字串中的字母轉換為大寫/小寫
LTRIM/RTRIM LTRIM(' abc')/RTRIM('abc ') 回傳'abc'/'abc' 去掉字串左邊/右邊的空格 同時去掉兩邊空格 RTRIM(LTRIM(' abc '))
REPLACE REPLACE('abc', 'b', 'x') 回傳 'axc' 將'abc'中的'b'替換為'x'
STUFF STUFF('abcd', 1, 2, '你好') 回傳 '你好cd' 洗掉從第1個字符開始,長度為2的字串,并插入 你好
2. 日期函式
GETDATE GETDATE() 回傳當前日期
DATEADD DATEADD(mm, -2, GETDATE()) 回傳當前日期-2月
DATEDIFF DATEDIFF(dd, '1989-07-14', GETDATE()) 回傳兩個日期之間的間隔
DATENAME DATENAME(DW, GETDATE()) 回傳 '星期幾' 以字串形式回傳當前日期指定的部分
DATEPART DATEPART(DW, GETDATE()) 回傳 一個星期的第幾天 以整數形式回傳當前日期指定的補分
3. 數學函式
CEILING/FLOOR CEILING(24.1)/FLOOR(24.4) 回傳 25/24 回傳大于24.1的最小整數、回傳小于24.1的最大整數
ROUND ROUND(748.35, 1) 回傳 748.40 四舍五入到小數點后1位
4. 系統函式
CONVERT CONVERT(VARCHAR(3), 123) 回傳 '123' 轉換資料型別
DATALENGTH DATALENGTH('1個逗逼') 回傳 7 回傳任何資料型別的位元組數,漢字2位元組

-------------------------------------------------------
--在這里撰寫SQL陳述句命令
--1.創建一個資料庫
create database MyDatabaseOne
--2.洗掉資料庫
drop database MyDatabaseOne
--3.創建資料庫的時候設定一些引數選項
create database MyDatabaseOne
on--指定主檔案的屬性
(
--配置主資料的選項
name='MyDatabaseOne',--住資料檔案的邏輯名稱
filename='E:\MySQLServerDatabase.mdf',--住資料檔案的實際保存路徑
size=5MB,--初始化大小
maxsize=200MB,--最大檔案大小
filegrowth=10%--每次增長

)
log on--指定日志檔案的屬性
(
--配置日志檔案的選項
name='MyDatabaseOne_log',--日志檔案的邏輯名稱
filename='E:\MySQLServerDatabase.ldf',--日志檔案的實際保存路徑
size=5MB,--日志檔案的初始大小
filegrowth=10%--每次增長
)
-------------------------在資料庫中創建一個表-------------------------
--將代碼環境切換到MyDatabaseOne
USE MyDatabaseOne
create table Departments
(
Auto int identity(1,1)primary key,
Departments nvarchar(50) not null,
)
--通過代碼,洗掉master資料庫下的某些表
USE master

--drop database --洗掉資料庫
drop table Table_1--洗掉表
drop table Table_1 where 字句--洗掉表中某一條

---創建一個員工表---
--<員工表>:
USE MyDatabaseOne
GO
create table Employees
(
EmpID int identity(1,1) primary key,//主鍵
EmpIDCard varchar(18) not null,
EmpName nvarchar(50) null,
EmpGender bit not null,
EmpJoinDate datetime,
EmpAge int,
EmpAddress nvarchar(300),
EmpPhone varchar(100),
DeptId int not null,
EmpEmail varchar(100),
)
drop table Employees
use MyDatabaseOne
create table Employees
(
EmpID int identity(1,1) primary key,
EmpIDCard varchar(18) not null,
EmpName nvarchar(50) null,
EmpGender bit not null,
EmpJoinDate datetime,
EmpAge int,
EmpAddress nvarchar(300),
EmpPhone varchar(100),
DeptId int not null,
EmpEmail varchar(100),
)

物體完整性:
primary key//(主鍵)約束 唯一識別每一條記錄的標志,可以由多列共同組成**只能有一個,不許重復,不許為null
identity//(自增)約束 列值自增,一般使用此屬性設定的列作為主鍵identtity(1,1)
unique//(唯一)約束 可以使用unique約束確保在非主鍵列中部存在重復值,但是值可以為null

域完整性:
check(檢查)約束//用于限制列中的值的范圍()
foreign key(外鍵)約束//一個表中的foreign key指向另一個表中的primary key
default(默認值)約束//用于向列種插入默認值default'中國'
not null(非空)約束//用于強制列不接受null值
參考完整性:
參考完整性是指兩個表的主鍵和外鍵的資料對應一致,它建立在外鍵和主鍵的關系之上,在sql server中,參考完整性的作用表現在一下3個方面
1.禁止在子表中添加主表中不存在的記錄
2.禁止修改主表的值
3.禁止洗掉子表中的有對應記錄的主表記錄
用戶自定義完整性:
主要是規則rule、約束constraint和觸發器trigger
StudentNum int references Tb_Student(StudentNum) 引入例子!
-------------------------SQL陳述句入門-------------------------
DDL(資料定義語言,建表,建庫等陳述句)
DML(資料操作語言)
DCL(資料控制語言)

SQL陳述句中字串用 單引號、單等號
SQL陳述句不區分大小寫(取決與排序規則)

-----------------------------------------------------------------------向學生表中插入一條記錄
--insert into 表名(列1,列2,列3) values(值1,值2,值3)
--1,自動編號列,默認就會自動增長,所以不需要(默認情況下也不能向自動編號列插入值)
注意:如果欄位型別為varchar或者datetime,則必須使用單引號引起來
賦值與查看例子
insert into Tb_Teacher(TeacherName,TeacherAge,TeacherSalary,TeacherTel) 插入所有值(沒省略)
values('大蛇丸',25,999999,'15271000220')
select * from Tb_Teacher
insert into Tb_Teacher(TeacherName,TeacherTel) 插入部分值
values('火神','22022022022')
select * from Tb_Teacher
insert into Tb_Teacher
values('八神',25,88888,'11011011011') 插入所有值(省略)
select * from Tb_Teacher


同時插入多行資料
insert into Tb_Student
--values('200709002','凱奇',21,'法國','2007-09-02',3000.5) //values插入值
select '200709002','凱奇',21,'法國','2007-09-02',3000.5 union //select插入值(內容不需要())
select '200709003','saha',25,'印度','2007-09-02',1000.5 union
select '200709004','張小飛',21,'中國','2007-09-02',2000.5 //最后一行不需要union


-----------------------------------------------------------------------強行插入
--啟動自動編號列插入值
--啟動某個表的“自動編號列”手動插入值得功能
set identity_insert Tb_Teacher on
insert into Tb_Teacher(TeacherID,TeacherName,TeacherTel)
values(10086,'移動SB','10086')
set identity_insert Tb_Teacher off
select * from Tb_Teacher

--在SQL陳述句中的直接寫的字串中,如果包含中文,一定在字串前面加N
(因為當排序規則不是簡體中文的時候會亂碼)
例子
values(10086,N'移動SB','102016/7/13086')

-----------------------------------------------------------------------打開和關閉查詢結果視窗:ctrl+r

-----------------------------------------------------------------------更新陳述句:
--update 表名 set 列=新值,列2=新值,....where 條件
--update陳述句如果不加where條件,那么表示對表中所有條件都進行修改,所以一定要加where條件
select * from Tb_Teacher
update Tb_Teacher set TeacherAge=TeacherAge+1,TeacherName = TeacherName+'(男)' where TeacherAge = 26
update Tb_Teacher set Age=30 where Name='大蛇丸' or Age<25
select * from Tb_Teacher

--洗掉資料陳述句
--delete from 表名 where....
--delete陳述句如果不加where條件,表示將表中所有的資料洗掉,加上where條件后,會按照where條件進行洗掉
--洗掉Tb_Teacher表中的所有資料,自動編號沒有回復到默認,仍然繼續編號
delete from Tb_Teacher
select * from Tb_Teacher
insert into Tb_Teacher
values('胡偉',25,200,'15271100220')
select * from Tb_Teacher
insert into Tb_Teacher
values('楊磊',26,300,'15271200220')
insert into Tb_Teacher
values('小軍',27,400,'15271300220')
insert into Tb_Teacher
values('張衡',28,500,'15271400220')

外鍵關系-級聯,
級聯洗掉將先洗掉子表中的相應記錄,再洗掉主表記錄


--truncate table 表名
--如果要洗掉表中全部資料,那么建議使用truncate
--truncate特點:
--1.truncate陳述句不能跟where條件(無法根據條件來洗掉,只能全部洗掉)
--2.truncate同時自動編號恢復到初始值
--3.使用truncate洗掉表中的所有資料要比delete效率高的多的多,
--4.truncate 洗掉資料,不觸發觸發器
------------------------------------------------------------------------------------------------------------------------
use mstanford
drop table Tb_Student
create table Tb_Student
(
StudentNo varchar(20) primary key,
StudentName nvarchar(20) not null,
StudentAge int not null check(StudentAge>=20 and StudentAge<=30),
County nvarchar(20) not null default('中國'),
StuTime datetime not null,
Tuition money not null
)
select * from Tb_Student
update Tb_Student set StuTime='2009-09-01' --更新資料

------------------------增加資料 INSERT INTO
select * from Tb_Student_Coures
insert into Tb_Student_Coures values ('200709003','.net','2009-09-09','通過') --增加資料
insert into Tb_Student_Coures values ('200709004','jap','2009-09-09','NULL')
insert into Tb_Student_Coures values ('200709002','java','2009-09-09','通過')

update Tb_Student_Coures set CouresTime='2008-08-08',Notes='通過'where StudentNo='200709003' --更具條件更新資料


------------------------簡單查詢 SELECT
select * from mstanford.dbo.Tb_Student --查詢資料
select studentno from mstanford.dbo.Tb_Student order by studentno desc --查詢并且按降序排列 ASC(縮寫ascending)表示升序 DESC(縮寫descending)表示降序
insert into mstanford.dbo.Tb_Student_Coures values('200709004','jsp','2008-08-08','取消考試')--增加資料
insert into mstanford.dbo.Tb_Student_Coures values('200709004','java',2008-01-02,'NULL')
select StudentNo,Notes from mstanford.dbo.Tb_Student_Coures--查詢多列資料
select * from mstanford.dbo.Tb_Student_Coures--查看所有資料簡寫
select SCNo,StudentNo,CouresName,CouresTime,Notes from mstanford.dbo.Tb_Student_Coures--查看所有資料完整寫
select distinct studentno from mstanford.dbo.Tb_Student_Coures--distinct查看資料并且去掉重復
select StudentNo as 學號,SCNo as 編號,CouresName as 課程名稱,CouresTime as 課程時間,Notes as 備注 from mstanford.dbo.Tb_Student_Coures--查詢使用別名


------------------------排序查詢 ORDER BY
update Tb_Student_Coures set CouresTime='2008-01-02' where SCNo='43' --更改
select * from Tb_Student_Coures order by CouresTime DESC --查詢所有某列降序
select * from Tb_Student_Coures order by StudentNo desc,CouresTime desc --查詢所有多列降序

------------------------查詢限定行 TOP N PERCENT
select top 3 * from Tb_Student_Coures --查詢表中前3行
select top 1 percent * from Tb_Student_Coures --查詢表中1%行(percent百分比)
select top 50 percent * from Tb_Student order by StudentNo desc,Tuition asc --查詢表中1%行(percent百分比)StudentNo 降序,Tuition 降序

------------------------條件查詢 WHERE --邏輯運算子 'NOT' 'AND' 'OR' 'IS NULL'回傳TRUE 'IS NOT NULL'回傳FALSE
select * from mstanford.dbo.Tb_Student_Coures where Notes='通過' -------------單條件查詢(使用比較運算子)
select * from mstanford.dbo.Tb_Student_Coures where SCNo>=40 -------------單條件查詢(使用比較運算子)
select * from mstanford.dbo.Tb_Student_Coures where SCNo>40 AND notes='通過' -------------多條件查詢(使用邏輯運算子)
select * from mstanford.dbo.Tb_Student_Coures where Notes is NULL -------------查詢表中 Notes值NULL空的行
select * from mstanford.dbo.Tb_Student_Coures where Notes is not null -------------查詢表中 Notes值為NOT NULL的行

select * from mstanford.dbo.Tb_Student_Coures where Notes != '通過' -------------查詢表中 notes值不是'通過'的行(不檢查值為NULL)的行
select * from mstanford.dbo.Tb_Student_Coures where not Notes = '通過' -------------查詢表中 notes值不是'通過'的行(不檢查值為NULL)的行

select * from mstanford.dbo.Tb_Student_Coures where (StudentNo='200709002' or StudentNo='200709003') and CouresName='.net' -------------理解運算優先級ADN > OR,()限制優先級

------------------------SQL Server內置函式,可以與INSERT UPTATE DELETE等一起使用:1.字串函式,2.日期函式,3.數字函式,4.系統函式

select STUFF(PName,1,0,'拳皇_') as 名稱,WeaponID,SkillID from DB_King_Fighters.dbo.player --使用stuff洗掉并且插入字符
select upper(CouresName) as 課程名稱 from mstanford.dbo.Tb_Student_Coures ------------- 查詢表中課程名稱,并將小寫轉換成大寫
select * from mstanford.dbo.Tb_Student_Coures where len(CouresName)>3 -------------查詢表中課程名稱大于3的選課資訊
select * from mstanford.dbo.Tb_Student_Coures where CouresTime<GETDATE() -------------查詢選課日期再當前日期之前的選課資訊
select * from mstanford.dbo.Tb_Student_Coures where DATENAME(DW,CouresTime)='星期三' -------------查詢選課為星期三的選課資訊

select CONVERT(int,SUBSTRING(StudentNo,1,2))+CONVERT(int,SUBSTRING(StudentNo,3,2)) as 學號 from mstanford.dbo.Tb_Student_Coures -------------理解substring,convert

--CONVERT(int,SUBSTRING(StudentNo,1,2))--SUBSTRING(實體,截取開始位,截取結束位)
select * from mstanford.dbo.Tb_Student_Coures
update mstanford.dbo.Tb_Student_Coures set CouresTime='2009-09-09',CouresName='jsp',StudentNo='200709004' where SCNo=43
delete from mstanford.dbo.Tb_Student_Coures where SCNo=39--理解洗掉表中某一行
select top 2 StudentNo,Notes from mstanford.dbo.Tb_Student_Coures where Notes='通過' order by StudentNo desc--理解查表行數,查表列數,查表條件,查表排序一起運用
select * from mstanford.dbo.Tb_Student_Coures where SUBSTRING(CouresName,1,1)='j' and Notes is not null--理解is not null的用法,不能使用!= null

------------------------------------------------------------LIKE 運算子
------------------------------------------------------------通配符 % 任意0個或者多個字符
select ProductName,UnitPrice from Products where ProductName like 'c%'--通配符%表示任意字符的匹配(以C開頭)
select ProductName,UnitPrice from Products where ProductName like '%t'--(以T結尾的)
select ProductName,UnitPrice from Products where ProductName like 'c%t'--(以c開頭以t結尾)
select ProductName,UnitPrice from Products where ProductName like '%t%'--(包含t)
------------------------------------------------------------通配符 _ 任意單個字符
select ProductName,UnitPrice from Products where ProductName like 't_fu'
select ProductName,UnitPrice from Products where ProductName like '_____'--產品名稱長度是5個字符的產品

select ProductName,UnitPrice from Products where ProductName like '_e%'--查詢第二個位元組為e的產品名稱
select ProductName,UnitPrice from Products where ProductName like '_a%' and QuantityPerUnit like '%pkgs%'
------------------------------------------------------------通配符 [] 指定一系列的字符,只要滿足這些字符其中之一且出現在[]通配符的位置的字串就滿住查詢條件
select ProductName from Products where ProductName like '%[_]%'--名稱中帶有_的資料
update Products set ProductName='abc_123' where ProductName='huwei_520' --更改資料
select ProductName,UnitPrice from Products where ProductName like '%[abfg]'--名稱最后一位是[abfg]的資料


------------------------------------------------------------IN 運算子(相對于or,IN簡捷,后面可以是SQL陳述句)
select ProductName,SupplierID from Products where SupplierID=1 or SupplierID=4 or SupplierID=3
select ProductName,SupplierID from Products where SupplierID in(1,3,4) --同上兩句相等


------------------------------------------------------------BETWEEN 運算子
select ProductName,UnitPrice from Products where UnitPrice between 6 and 10 order by UnitPrice desc--unitprices價格在6-10之間的產品名稱和單價資料,unitprices按降序排列,排序規則放在陳述句最后
select LAStName,BirthDate from Employees where BirthDate between '1952-01-01' and '1960-01-01'--查詢出生區間出生日期between

------------------------------------------------------------聚合函式 SUM MAX MIN AVG COUNT
--DATE type 求min/max按照時間的先后排列的,日期越早月小,
--CHAR type 求min/max按照搜首字母A-Z的順序排列,越后越大
--漢字 type 求min/max按照全拼拼音進行比較,若首字母形同則比下一個字符
------------------------------------------------------------SUM聚合函式
select top 10 SUM(UnitPrice) AS 前十價格之和 from Products--前十價格之和
select * from Products
select SUM(UnitPrice*Quantity) AS 所有商品價格和 from [Order Details] where OrderID='10249'--OrderID是10249所有商品價格的和

------------------------------------------------------------MAX/MIN函式
select MAX(UnitPrice) AS 最高價格產品 from Products--最高價格產品
select MIN(BirthDate) AS 年紀最大員工 from Employees--年齡最大的員工生日
------------------------------------------------------------AVG集函式
select AVG(UnitPrice) AS 商品價格平均價 from Products
------------------------------------------------------------COUNT函式
select COUNT(ProductName) AS 商品個數 from Products--商品個數
select COUNT(*) AS 記錄數 from Products--查詢所有記錄數(包括空值)

------------------------------------------------------------多聚合函式一起用
select COUNT(*) AS 總記錄數,AVG(UnitPrice) AS 平均價格, MAX(UnitPrice)AS 最高價格 from Products--多聚合函式的使用

------------------------------------------------------------分組查詢
------------------------------------------------------------GROUP BY字句
分組查詢語法: SELECT 分組列, 聚合列 FROM 表名 WHERE 普通列 GROUP BY 分組列 HAVING 分組列, 聚合列 ORDER BY 分組列, 聚合列
select EmployeeID,MIN(OrderDate) AS 每個員工最早訂單時間 from Orders group by EmployeeID order by EmployeeID ASc--聚合函式與分組查詢共用
------------------------------------------------------------HAVING字句
select EmployeeID,COUNT(*) AS 訂單數量 from Orders group by EmployeeID having COUNT(*)>100
select EmployeeID,COUNT(*) AS 訂單數量 from Orders group by EmployeeID having COUNT(*)>100 and EmployeeID>2--和下一句對比,如果不是判斷結果集,那么可以用下面的寫法
select EmployeeID,COUNT(*) AS 訂單數量 from Orders where EmployeeID>2 group by EmployeeID having COUNT(*)>100
select * from Orders

------------------------------------------------------------作業1
select FirstName,LAStName,HomePhone from Employees where HomePhone like '(%)_5%122' --%_用法
select count(ProductName) AS 商品數, avg(unitprice) AS 平均價格,SUM(unitprice) AS 單價和, max(unitprice) AS 最高價, min(unitprice) AS 最低價 from Products--聚合函式使用
select ProductID AS 產品編號, MAX(UnitPrice*Quantity) AS 訂單額 from [Order Details] where ProductID>70 and OrderID>11020 GROUP BY ProductID order by MAX(UnitPrice*Quantity) desc--聚合函式 group by的使用

------------------------------------------------------------上機 1模糊查詢
select ProductName,UnitPrice from Products where ProductName like 'c_[a-f][^g-z]%'
select * from Products
UPDATE Products set ProductName='[楊磊牛逼]' where ProductID=1
select ProductName,UnitPrice from Products where ProductName like '%[%]%'--包含%的產品名稱和單價
select ProductName from Products where ProductName like '%[_]%'
select ProductName from Products where ProductName like '%[[]%]%'

select * from Employees where (City='london' or City='kirkland' or City='seattle') and HomePhone like '%2'--和下面的一樣
select * from Employees where City in ('london','kirkland','seattle') and HomePhone like '%2'

------------------------------------------------------------2聚合函式
select AVG(datediff(YY,BirthDate,GETDATE())) AS 平均年紀,
MAX(datediff(YY,BirthDate,GETDATE())) AS 最大年紀
from Employees

select COUNT(*) AS 記錄次數,COUNT(Region) AS Region欄位值的個數 from Employees--計算記錄次數和Region not is null 的次數
select * from Orders
select CustomerID,OrderID from Orders where OrderID>11011 and EmployeeID>2
select CustomerID,COUNT(*) as 訂單數量 from Orders where OrderID>11011 group by CustomerID having COUNT(*)>2

select * from Customers
select Country as 國家,COUNT(CustomerID) as 客戶數量 from Customers group by Country
select Country as 國家,COUNT(CustomerID) as 客戶數量,CompanyName as 公司名稱名稱 from Customers where CompanyName like 'b%' group by Country,CompanyName
select Country as 國家,COUNT(CustomerID) as 客戶數量,CompanyName as 客戶公司名稱,Country as 國家 from Customers
where CompanyName like 'b%' and LEN(Country) between 5 and 10 group by Country,CompanyName,Country --理解集合函式,between運算子group by的用法

------------------------------------------------------------表的基本連接
------------------------------------------------------------兩表連接
use Northwind
--查詢屬于beverages和condiments類的商品名,切商品名以'c'開頭
select Categories.CategoryID,Categories.CategoryName,--種類ID,種類名稱
Products.CategoryID,Products.ProductName--商品.種類ID,商品.商品名稱
from Categories,Products
where Categories.CategoryID=Products.CategoryID--兩張表的連接條件
and CategoryName in('beverages','condiments')--查詢類別(查詢這兩個種類)
and ProductName like 'c%'

--select TB_A.A,TB_B.C FROM TB_A,TB_B WHERE TB_A.C=TB_B.C
select * from Categories
select * from Products
select * from [Order Details]

--TB_A 表和 --TB_B都存在欄位C,所以在select陳述句中使用該欄位時,一定要知名其所在的表,如TB_A.C、TB_B.C,其他的充滿欄位要需要進行同樣的處理,否則資料庫系統會報錯
--使用sel server關鍵字作為表名,列名的時候,需要使用“[]”包括起來,例如create table [order]
--select陳述句首先執行from字句,由于定義表別名是在from字句中執行,而在其他子句中使用,所以在select陳述句的任何子句中都可以使用表的別名
select c.CategoryID,c.CategoryName,
p.CategoryID,p.ProductName,
o.OrderID
from Categories as c,Products as p,[Order Details] as o
where c.CategoryID=c.CategoryID
and p.ProductID=o.ProductID
and CategoryName in('beverage','condiments')
and ProductName like 'c%'
and o.OrderID>1060

------------------------------------------------------------內連接
--內連接也稱為等同連接,回傳的結果是兩個表中所有相匹配的資料,舍棄不匹配的資料
select * from Products
select * from Categories
select Categories.CategoryID as 種類ID,Categories.CategoryName as 種類名稱,
Products.CategoryID as 種類ID,Products.ProductName as 種類名稱
from Categories join Products
on Categories.CategoryID=Products.CategoryID
where CategoryName in('beverages','condiments')
and ProductName like 'c%'

select * from Customers
select * from Orders

select kh.CompanyName as 客戶公司,kh.ContactName as 客戶名字,kh.Phone as 客戶電話,dd.OrderID as 訂單編號,dd.OrderDate as 訂單日期
from Customers as kh,Orders as dd
where kh.CustomerID=dd.CustomerID
order by 訂單編號

select kh.CompanyName as 客戶公司,kh.ContactName as 客戶名字,kh.Phone as 客戶電話,dd.OrderID as 訂單編號,dd.OrderDate as 訂單日期
from Customers as kh left join Orders as dd
on kh.CustomerID=dd.CustomerID
order by 訂單編號

------------------------------------------------------------外連接
select * from Customers
select * from Employees
select kh.City as 客戶所在城市,yg.FirstName+yg.LastName as 員工姓名,kh.ContactName as 客戶姓名
from Employees as yg right join Customers as kh
on kh.City=yg.City


--全外部鏈接full on...on
select * from Customers
select * from Orders
select Orders.OrderID 訂單編號,Orders.OrderDate 訂單日期,Customers.CompanyName 客戶公司
from Customers full join Orders
on Customers.CustomerID=Orders.CustomerID

-----------------------------------------------------------SQL SERVER執行順序

--SELECT...
--FROM...
--WHERE...
--GROUP BY...
--HAVING...
--ORDER BY...


--查詢供貨商的公司名稱和所供應的商品名稱
select * from Suppliers
select * from Products
select * from [Order Details]
select s.CompanyName,p.ProductName
from Suppliers s,Products p
where s.SupplierID=p.SupplierID

select s.CompanyName,p.ProductName
from Suppliers s join Products p
on s.SupplierID=p.SupplierID

select s.CompanyName,p.ProductName,o.OrderID
from Suppliers s,Products p,[Order Details] o
where s.SupplierID=p.ProductID and p.ProductID=o.ProductID

select Suppliers.CompanyName,Products.ProductName,[Order Details].OrderID
from Suppliers join Products on Suppliers.SupplierID = Products.SupplierID join [Order Details] on Products.ProductID = [Order Details].ProductID

select * from Customers
select * from Suppliers
select c.CompanyName 客戶姓名,c.[Address] 客戶地址,s.CompanyName 供貨商公司,s.ContactName 供貨商聯系人
from Customers c left join Suppliers s
on c.City=s.City

select * from Orders
select * from Employees
select * from Customers
select Orders.OrderID as 訂單編號,Employees.FirstName+Employees.LastName as 負責人姓名,Customers.CompanyName as 下訂單公司名稱
from Employees right join Orders on Orders.EmployeeID=Employees.EmployeeID left join Customers on Orders.CustomerID=Customers.CustomerID



---------------------------------------------------------------------------第二階段
1、資料庫設計階段
需求分析:收集資訊
概念設計:標識物體、標識屬性、標識關系-》E-R圖[物體(Entity)關系(Relationship)圖] 軟體vision
邏輯設計:E-R圖轉換成相應的表并通過3大范式進行審核
物理設計:選擇合適物理實作
實施:
運行和維護:

范式(Normal Formate)NF
第一范式 確保每一列的原子性,不可再拆分
第二范式 除了主鍵外,所有的列都依賴于主鍵,并且沒有一個物體是組合主鍵
不符合第二范式會有問題
1資料冗余
2跟新例外
3插入例外
4洗掉例外
第三范式 非關鍵字對非主鍵的間接函式依賴


ER模型 E-R模型圖 物體(Entity)關系(Relationship)圖 vision
PowerDesigner 概念資料模型
PhysicalDiagram 物理圖

物體:物體是現實生活中區別于其他事物,具有自己屬性的物件,同一類物體的所有實體就是構成該物件的物體集,
屬性:屬性是物體的特征
關系:物體之間存在的聯系


關系分類
1對1關聯 1:1屬于
班級 輔導員
一個班級只有一個輔導員
一個輔導員只負責一個班級
1對多關聯 1:N擁有
班級 學生
一個班級有多個學生
多個學生屬于一個班級
多對1關聯 N:1

辦事處與員工之間是一對多的關系,反之員工與辦事處之間就是多對一的映射基礎

多對多關聯 N:M
學生 教師
一個學生有多名老師(語文數學)
一個老師教多名學生


部門中擁有很多員工(1:N)
一個員工可以管理一個部門(1:1)
辦事處中擁有很多員工(1:N)
員工可以存在很多技能(M:N)

映射基數:
1:1(員工管理部門)
1:N(部門擁有員工)
N:1(員工屬于部門)
M:N(員工和技能)

--------------------------------------------------------------------------------------------------
變數 運算子 批處理陳述句 流程控制陳述句

全域變數
@@ERROR 回傳執行的上一個陳述句的錯誤號
@@IDENTITY 回傳最后插入的標識值
@@ROWCOUNT 回傳受上一陳述句影響的行數
@@SERVERNAME 回傳運行 SQL Server 的本地服務器的名稱
@@MAX_CONNECTIONS 回傳允許同時進行的最大用戶連接數

print @@version

區域變數:由用戶定義的變數,其作用域在定義它的代碼塊中(指存盤程序,函式,匿名的T—SQL代碼塊),一般是在兩個GO之間
區域變數:以@開頭,由用戶定義,先宣告再賦值最后使用

宣告:
declare @變數名 資料型別
宣告并賦值:
declare @變數名 資料型別=值

給變數賦值:
set @變數名 = 值
select @變數名 = 值
select @變數名 = 列名 from 表

使用變數:
列印變數:
print @變數名
select @變數名
select @變數名 as 別名

set 將已經確定的常量賦值給區域變數
select 將從資料庫中查詢的結果賦值給區域變數

go陳述句的作用:
go前面的陳述句執行完之后,才會執行其后的代碼
作為批處理陳述句的結束,go之前宣告的變數,在go之后不能使用

--------------------------------------------------------------------------------使用T-SQL編程
create database Company_DB
on(
name='Company_DB',
filename='E:\MySQLServerDatabase\Company_DB.mdf'

)
log on(
name='Company_DB_log',
filename='E:\MySQLServerDatabase\Company_DB.ldf'
)
create table Office
(
OfficeCode nvarchar(20) primary key,--辦公司代號
OfficeAddress nvarchar(100) not null unique--辦公司地址
)
create table Department
(
DeptNo nvarchar(20) primary key, --部門代號
DeptName nvarchar(20) not null unique,--部門名稱
Principal nvarchar(20) --部門負責人
)
create table Employee
(
EmpNo nvarchar(20) primary key,--員工號
EmpName nvarchar(20) not null,--員工名字
EmpAddress nvarchar(100) not null,--員工地址
EmpPhone varchar(12) not null,--員工電話
Birthday datetime not null,--員工生日
HireDate datetime not null,--入職時間
DeptNo nvarchar(20) foreign key references Department(DeptNo),--外鍵
OfficeCode nvarchar(20) foreign key references Office(OfficeCode)--外鍵
)

insert into Office
values ('C01','中山北路200號')
insert into Office
values ('C02','北京中路35號')
insert into Office
values ('C03','福州路10號')

insert into Department(DeptNo,DeptName)
values ('D01','技術部')
insert into Department(DeptNo,DeptName)
values ('D02','市場部')
insert into Department(DeptNo,DeptName)
values ('D03','行政部')

insert into Employee
values ('E001','Tom','凱撒大廈501','021-45364743','1980-10-02','2004-04-06','D01','C01')
insert into Employee
values ('E002','Jack','凱撒大廈502','021-45364743','1980-01-03','2004-05-16','D01','C01')
insert into Employee
values ('E003','White','凱撒大廈503','021-45364743','1980-01-04','2003-05-06','D02','C01')
insert into Employee
values ('E004','Smith','凱撒大廈504','021-45364743','1980-05-02','2000-05-22','D02','C02')
insert into Employee
values ('E005','John','凱撒大廈505','021-45364743','1980-06-01','2004-02-13','D02','C02')
insert into Employee
values ('E006','Slider','凱撒大廈506','021-45364743','1982-08-02','2005-03-12','D03','C02')
insert into Employee
values ('E007','Buth','凱撒大廈507','021-45364743','1983-02-12','2006-05-06','D03','C02')
insert into Employee
values ('E008','Jennifer','凱撒大廈508','021-45364743','1980-11-02','2004-05-16','D01','C03')
insert into Employee
values ('E009','Kelly','凱撒大廈509','021-45364743','1980-01-23','2004-05-22','D01','C03')
insert into Employee
values ('E010','Winston','凱撒大廈510','021-45364743','1978-10-02','2002-09-06','D01','C03')
insert into Employee
values ('E011','Joy','凱撒大廈511','021-45364743','1980-11-12','2004-12-06','D01','C03')

drop table Office
drop table Department
drop table Employee

select * from Office
select * from Department
select * from Employee

use Company_DB

declare @DeptNo nvarchar(10)='D01'--宣告變數并賦值
select @DeptNo

declare @EmpNo nvarchar(10)='胡偉'--宣告變數
print @EmpNo

--------------------------------------------------------------------------------
use Company_DB
go
--查詢Dept='D10'的員工號
declare @DeptNo nvarchar(10)='D01'
select EmpNo from Employee where DeptNo=@DeptNo

--把查詢的EmpNo的查詢結果最后一條記錄值賦值給區域變數@EmpNo
declare @EmpNo nvarchar(10) --定義變數
declare @DeptNo nvarchar(10)='D01'--定義點亮并且賦值
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo
select @EmpNo

--------------------------------------------------------------------------------
--找出一部門中工齡最大的員工(按照工齡升序排列,自動取最后一條資料賦值)
declare @EmpNo nvarchar(10)
declare @DeptNo nvarchar(10)='D01'
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo group by EmpNo order by MAX(DATEDIFF(yyyy,hiredate,getdate())) asc
print @EmpNo--輸出顯示

--更新部門負責人 E010 'D01'
update Department set principal = @EmpNo where DeptNo = @DeptNo


--找出二部門中工齡最大的員工(按照工齡升序,自動取最后一條資料賦值)
set @DeptNo='D02'--為變數@DeptNo重新復制
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo group by EmpNo order by MAX(DATEDIFF(yyyy,hiredate,getdate()))
print @EmpNo
update Department set Principal=@EmpNo where DeptNo=@DeptNo

--找出三部門中工齡最大的員工(按照工齡升序,自動取最后一條資料賦值)

set @DeptNo='D03'
select @EmpNo=EmpNo from Employee where DeptNo=@DeptNo group by EmpNo order by MAX(DATEDIFF(yyyy,hiredate,getdate()))
print @EmpNo
update Department set Principal=@EmpNo where DeptNo=@DeptNo

go
select * from Department
go

print '錯誤號碼'+convert(nvarchar(225),@@error
select @@VERSION as '版本代號'

------------------------------------------------運算子-----------------------------------
declare @OptNumber int=12436
--print '轉換之前'+@OptNumber 失敗int要想和varchar格式一起列印需要把int轉換成varchar
print '轉換前:'+convert(varchar(5),@optNumber)
declare @reverse varchar(5)
--取除個位數
declare @unit int = @OptNumber%10--6
set @reverse=(CONVERT(varchar(1),@unit))--6賦值給倒序變數,賦值順序左→右
print '逆序number:'+@reverse
--去掉個位數,變數OptNumber將變成1243
set @OptNumber=@OptNumber/10--1243
set @unit=@OptNumber%10--3
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse
set @OptNumber=@OptNumber/10--124
set @unit=@OptNumber%10--4
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse
set @OptNumber=@OptNumber/10--12
set @unit=@OptNumber%10--2
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse
set @OptNumber=@OptNumber/10--1
set @unit=@OptNumber%10--1
set @reverse=@reverse+CONVERT(varchar(1),@unit)
print '逆序number:'+@reverse

-----------------求1,2,3........100之間的奇數和
declare @tableNum table(Num int)--雖然求奇數不需要table型別變數,但是為了演示位運算子,所以定義table型別變數以便查詢
declare @loop int =1
while @loop<=100--回圈次數
begin
insert into @tableNum values(@loop)
set @loop=@loop+1
end
select SUM(num) from @tableNum where Num & 1=1
-----練習
declare @table table(num int)
declare @i int =1
while @i<=100
begin
insert into @table values (@i)
set @i=@i+1
end
select sum(num) from @table where num % 2=1
------------------------------ALL關鍵字----------------------
--ALL:將特定值與查詢的結果集中所有的資料進行比較,若結果集中資料都滿足該條件則回傳結果為true,否則結果為false
--語法:
--特定值 比較運算子 ALL(查詢陳述句)
create table Expertise(
SKillName nvarchar(20),
SKillLevel int,
EmpNo nvarchar(20)
)
insert into Expertise values('C','2','E010')
insert into Expertise values('C','1','E03')
insert into Expertise values('C','2','E02')
insert into Expertise values('C','3','E008')
insert into Expertise values('C','2','E005')
insert into Expertise values('C#','4','E006')
insert into Expertise values('C#','3','E007')
insert into Expertise values('DELPHI','1','E009')
insert into Expertise values('JAVA','2','E004')
SELECT * FROM Expertise

IF 2<=ALL(SELECT SKillLevel FROM Expertise)
PRINT '全部員工技能都通過了2級'
ELSE
PRINT '有員工技能不達標,還需要培訓'


-------------------------------ANY關鍵字---------------------
--ANY:將特定值與查詢的結果集中所有的資料進行比較,若結果集中任意一個資料滿足該條件則回傳結果為true,否則結果為false
--語法:
--特定值 比較運算子 ANY(查詢陳述句)
select * from Expertise
--if 0<=ANY(SELECT SKillLevel FROM Expertise)
if 2<=ANY(SELECT SKillLevel FROM Expertise where EmpNo='E010')
PRINT '已經有員工技能超過了2級'
ELSE
PRINT '全部員工的技能不達標,需要加強練習'

-------------------------------EXISTS關鍵字---------------------
--Exists:判斷查詢的結果集中是否存在資料,若存在資料,則結果為true,否則結果為false
--注意:可以使用not exists
select * from Employee
if Exists (SELECT * FROM Employee WHERE EMPADDRESS IS NULL)
PRINT '有員工沒有填寫住址'
ELSE
PRINT '全部都填寫住址了'
----------------------------------------------------SQL流程控制陳述句-------------
--BEGIN-END
--作用:相當于JAVA,C#中{}
--注意
--當陳述句塊中陳述句多于一句時,需要使用begin-end
--degin-end之間必須只有存在一條陳述句
create table Salary(
Id int identity(1,1) primary key,
EmpNo NVARCHAR(20) FOREIGN KEY references Employee(EmpNo),
Salary money,
StartTime datetime
)
select * from Salary
select * from Expertise
select * from Office
select * from Department
select * from Employee

insert into Salary values ('E001','5000','2004-04-06 00:00:00')
insert into Salary values ('E002','6500','2004-05-16 00:00:00')
insert into Salary values ('E003','5500','2003-05-06 00:00:00')
insert into Salary values ('E004','7200','2000-05-22 00:00:00')
insert into Salary values ('E005','5000','2004-02-13 00:00:00')
insert into Salary values ('E006','8000','2005-03-12 00:00:00')
insert into Salary values ('E007','11000','2006-05-06 00:00:00')
insert into Salary values ('E008','4800','2004-05-16 00:00:00')
insert into Salary values ('E009','6700','2004-05-22 00:00:00')
insert into Salary values ('E010','8000','2002-09-06 00:00:00')
insert into Salary values ('E011','9500','2004-12-06 00:00:00')

--如果某個員工的技能等級已經達到4級以上且最高,給這個員工增加基本工資500
declare @emp nvarchar(10)
declare @level int
declare @salary money
--查詢最高技能等級的員工
select @emp=EmpNo from Expertise order by SKillLevel
print @emp--E006
select @level=MAX(SKillLevel) from Expertise
print @level--4
if @level>=4
begin
select @salary=Salary from Salary where EmpNo=@emp
insert into Salary values (@emp,@salary+500,GETDATE())
end
GO

-------------------------------------IF ELSE 條件陳述句-------------------------------------
/**
if-else
作用:進行條件判斷
作業原理:條件成立執行if陳述句塊,不成立else陳述句塊
注意:
else子句可以省略
在if,else子句均可以嵌套if-else結構
*/
declare @worktime int
declare @emp nvarchar(10)
declare @salary money
select @emp=EmpNo,@worktime=DATEDIFF(YYYY,hireDate,GETDATE()) from Employee order by DATEDIFF(YYYY,hireDate,GETDATE()) asc
print @emp
if @worktime>=4
begin
select @salary=Salary from Salary where EmpNo=@emp
insert into Salary values (@emp,@salary+1000,GETDATE())
end
select * from Salary

-------------------------------------WHILE 陳述句-------------------------------------
/*
while
作用:進行回圈
作業原理:先判斷后執行
**/
select * from Expertise

declare @count int
while(1=1)--無限回圈
begin
select @count=COUNT(*) from Expertise where SKillName like '%c%' and SKillLevel<3
if(@count>0)
begin
update Expertise set SKillLevel+=1 where SKillName like '%c%' and SKillLevel<3
end
else
break--沒有員工C語言技能低于3級后就退出回圈
end
----------------------------------CASE 分支陳述句--------------------------------------------------
/*
case-end
作用:類似多重條件結構,用于進行多路分支
case 欄位名
when 值1 then 回傳值1
when 值2 then 回傳值2
...
else 回傳值n
end
作業原理:將欄位的值逐一與when陳述句之后的值進行匹配,若存在匹配項,則回傳then之后值,若不存在匹配項,則回傳else之后回傳值,其中else子句可以省略
case
when 條件1 then 回傳值1
when 條件2 then 回傳值2
...
else 回傳值n
end
作業原理:將逐一判斷when陳述句之后的條件,若條件為真,則回傳then之后值,若條件為假,則回傳else之后回傳值,其中else子句可以省略
*/
create table TimeWork(
Id int identity(1,1) primary key,
EmpNo nvarchar(10),
WorkState nvarchar(20),
WorkDate datetime
)
go
--創建表
insert into TimeWork values ('E001','病假','2008-10-11')
insert into TimeWork values ('E001','調休','2008-10-10')
insert into TimeWork values ('E001','正常上班','2008-10-08')
insert into TimeWork values ('E001','正常上班','2008-10-09')
insert into TimeWork values ('E001','正常上班','2008-10-12')
insert into TimeWork values ('E002','加班','2008-10-11')
insert into TimeWork values ('E002','休年假','2008-10-08')
insert into TimeWork values ('E002','休年假','2008-10-09')
insert into TimeWork values ('E002','正常上班','2008-10-10')
insert into TimeWork values ('E003','病假','2008-10-08')
insert into TimeWork values ('E003','正常上班','2008-10-09')
insert into TimeWork values ('E003','正常上班','2008-10-10')
insert into TimeWork values ('E003','正常上班','2008-10-11')
insert into TimeWork values ('E004','請假','2008-10-11')
insert into TimeWork values ('E004','休息','2008-10-08')
insert into TimeWork values ('E004','正常上班','2008-10-09')
insert into TimeWork values ('E004','正常上班','2008-10-10')
insert into TimeWork values ('E005','調休','2008-10-10')
insert into TimeWork values ('E005','正常上班','2008-10-08')
insert into TimeWork values ('E005','正常上班','2008-10-09')
insert into TimeWork values ('E005','正常上班','2008-10-11')
go
select * from TimeWork
drop table TimeWork

select WorkDate as 日期,
COUNT(case WorkState when '病假' then '0' end) as 病假,
COUNT(case WorkState when '調休' then '0' end) as 調休,
COUNT(case WorkState when '請假' then '0' end) as 請假,
COUNT(case WorkState when '正常上班' then '0' end) as 正常上班,
COUNT(case WorkState when '加班' then '0' end) as 加班,
COUNT(case WorkState when '休年假' then '0' end) as 休年假,
COUNT(case WorkState when '休息' then '0' end) as 休息,
COUNT(case WorkState when '其他' then '0' end) as 其他
from TimeWork group by WorkDate order by WorkDate desc

select * from TimeWork

select WorkDate,
病假=sum(case workstate when '病假' then 1 else 0 end),
調休=sum(case workstate when '調休' then 1 else 0 end),
請假=sum(case workstate when '請假' then 1 else 0 end),
正常上班=sum(case workstate when '正常上班' then 1 else 0 end),
加班=sum(case workstate when '加班' then 1 else 0 end),
休年假=sum(case workstate when '休年假' then 1 else 0 end),
其他=sum(case workstate when '其他' then 1 else 0 end)
from TimeWork
group by workdate
order by workdate desc
----------------------------------RETURN 陳述句--------------------------------------------------
/*
break:跳出回圈結構
return:跳出當前的批處理,而進入下一個批處理的執行
goto:必須和label一起配合使用,跳轉到相應label標簽處
*/

declare @num int=0
while(1=1)
begin
set @num+=1
if(@num>10)
RETURN
PRINT @num
end
go
select @@CONNECTIONS as '連接數量'
go

----------------------------------GOTO 陳述句--------------------------------------------------
SELECT * FROM Expertise
declare @num1 int
declare @num2 int
LABEL1:
PRINT '最高的技能級別就是6級了,不能再升級了'
WHILE(0=0)
BEGIN
SELECT @num1 =COUNT(*) FROM Expertise WHERE SKillLevel<2
IF(@num1>0)
BEGIN
UPDATE Expertise SET SKillLevel=SKillLevel+1
SELECT @num2=COUNT(*) FROM Expertise WHERE SKillLevel>6--查看Expertise表中SKillLevel列有幾行大于6的資料并且把這個資料賦值給@num2
IF(@num2>0)--如果@num2>0,
BEGIN
GOTO LABEL1--跳轉到錨點LABEL1執行
END
END
END

PRINT @@IDENTITY

--------------------------------------課后操作題-----------------------------------------------
create table orders
(
OrdersID nvarchar(100),
ProductID nvarchar(100),
[Date] datetime,
Number int,
[Money] int
)

insert into orders values ('SD-90102001','HW03202','1990-10-20 03:20:00','5','340')
insert into orders values ('SD-90112001','HW03212','1990-11-12 10:22:00','10','1880')
insert into orders values ('SD-90112001','HW03205','1990-11-24 12:25:35','30','2400')
insert into orders values ('SD-90102001','HW03211','1990-10-12 05:06:23','20','500')
insert into orders values ('SD-90102002','HW03211','1990-10-15 06:38:36','10','250')
insert into orders values ('SD-90082002','HW03212','1990-08-24 11:39:09','5','950')
insert into orders values ('SD-90082003','HW03202','1990-08-26 10:21:17','5','340')
insert into orders values ('SD-90052003','HW03223','1990-05-01 11:45:18','10','240')
insert into orders values ('SD-90062003','HW03224','1990-06-01 05:40:54','20','5000')
insert into orders values ('SD-90102003','HW03223','1990-10-17 06:26:25','5','350')
insert into orders values ('SD-90012005','HW03212','1990-01-08 07:28:22','7','1300')
insert into orders values ('SD-90022005','HW03223','1990-02-02 08:05:02','10','700')
insert into orders values ('SD-90012005','HW03202','1990-01-07 11:11:08','5','340')
insert into orders values ('SD-90062005','HW03202','1990-06-22 12:17:30','5','340')

drop table orders
SELECT * FROM orders
-------------一下兩張表union all的表
select
商品編號=ProductID,銷售詳情='銷售數量',
[1月]=sum(case datepart(month,[Date])
when 1 then Number
else 0
end),
[2月]=sum(case datepart(month,[Date])
when 2 then Number
else 0
end),
[3月]=sum(case datepart(month,[Date])
when 3 then Number
else 0
end),
[4月]=sum(case datepart(month,[Date])
when 4 then Number
else 0
end),
[5月]=sum(case datepart(month,[Date])
when 5 then Number
else 0
end),
[6月]=sum(case datepart(month,[Date])
when 6 then Number
else 0
end),
[7月]=sum(case
when datepart(month,[Date])=7 then Number
else 0
end),
[8月]=sum(case
when datepart(month,[Date])=8 then Number
else 0
end),
[9月]=sum(case
when datepart(month,[Date])=9 then Number
else 0
end),
[10月]=sum(case
when datepart(month,[Date])=10 then Number
else 0
end),
[11月]=sum(case
when datepart(month,[Date])=11 then Number
else 0
end),
[12月]=sum(case
when datepart(month,[Date])=12 then Number
else 0
end)
from orders
group by ProductID
union all
select
商品編號=ProductID,銷售金額='銷售金額',
[1月]=sum(case datepart(month,[Date])
when 1 then [money]
else 0
end),
[2月]=sum(case datepart(month,[Date])
when 2 then [money]
else 0
end),
[3月]=sum(case datepart(month,[Date])
when 3 then [money]
else 0
end),
[4月]=sum(case datepart(month,[Date])
when 4 then [money]
else 0
end),
[5月]=sum(case datepart(month,[Date])
when 5 then [money]
else 0
end),
[6月]=sum(case datepart(month,[Date])
when 6 then [money]
else 0
end),
[7月]=sum(case
when datepart(month,[Date])=7 then [money]
else 0
end),
[8月]=sum(case
when datepart(month,[Date])=8 then [money]
else 0
end),
[9月]=sum(case
when datepart(month,[Date])=9 then [money]
else 0
end),
[10月]=sum(case
when datepart(month,[Date])=10 then [money]
else 0
end),
[11月]=sum(case
when datepart(month,[Date])=11 then [money]
else 0
end),
[12月]=sum(case
when datepart(month,[Date])=12 then [money]
else 0
end)
from orders
group by ProductID

----------------一下答案,參考上面容易理解c
select
商品編號=ProductID,
[1月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 1 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 1 then [money]
else 0
end)),
[2月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 2 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 2 then [money]
else 0
end)),
[3月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 3 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 3 then [money]
else 0
end)),
[4月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 4 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 4 then [money]
else 0
end)),
[5月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 5 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 5 then [money]
else 0
end)),
[6月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 6 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 6 then [money]
else 0
end)),
[7月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 7 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 7 then [money]
else 0
end)),
[8月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 8 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 8 then [money]
else 0
end)),
[9月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 9 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 9 then [money]
else 0
end)),
[10月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 10 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 10then [money]
else 0
end)),
[11月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 11 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 11 then [money]
else 0
end)),
[12月銷清單]='數量'+convert(varchar,sum(case datepart(month,[Date])
when 12 then Number
else 0
end))+' '+'金額'+convert(varchar,sum(case datepart(month,[Date])
when 12 then [money]
else 0
end))
from orders
group by ProductID


--查看某個時間的月份
select datepart(month,[Date]) from orders where [date]='1990-10-20 03:20:00'

--上機階段1
---------------------------變數的定義和使用
/*
用戶狀態:待審核,已審核,被屏蔽
用戶角色:待審核會員,普通會員,VIP會員,超級管理員
用戶在剛注冊時狀態為待審核,角色是待審核會員,管理員進行確認和管理
*/
create table UserState(
Id int identity(1,1) primary key,
[State] nvarchar(100)
)
create table RoleInf(
Id int identity(1,1) primary key,
Rolename nvarchar(100),
Roledesc nvarchar(100),
Discount DECIMAL(3,2)
)
create table UserInf(
UserName nvarchar(50),
[PassWord] varchar(50),
RealName nvarchar(50),
Gender nvarchar(10),
IDCardNo varchar(20),
Email varchar(100),
Phone varchar(11),
[Address] nvarchar(200),
Balance money,
UserStateId int foreign key REFERENCES UserState(id),
UserRoleId int foreign key REFERENCES RoleInf(id),
PicUrl varchar(200)
)
drop table UserState
drop table RoleInf
drop table UserInf

select * from UserState
select * from RoleInf
select * from UserInf
--階段1
--指導部分
/*
用戶狀態:待審核、已審核、被屏蔽
用戶角色:待審核會員、普通會員、VIP會員、超級管理員
用戶在剛注冊時狀態為待審核,角色是待審核會員,管理員進行確認和管理
*/
declare @stateid int,@roleid int
insert into UserState values('待審核')
select @stateid=@@IDENTITY--使用select為區域變數賦值//當userstate用戶狀態表中添加資料以后@stateid資料會遞增改變
insert into RoleInf values('待審核會員','','1')
set @roleid=@@IDENTITY--使用set為區域變數賦值
--使用insert select union 陳述句多行插入
insert into userinf
select 'tom123','123456','tom','1','321032198008152919','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\tom.jpg' union all
select 'jack123','admin123','jack','1','321032198612126746','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\jack.jpg' union all
select 'Slider123','as123','Slider','1','321032198208213232','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\Slider.jpg' union all
select 'Micky123','888888','Micky','1','321032198910102322','[email protected]','','','1000',@stateid,@roleid,'d:\prt\images\Micky.jpg'
GO
select * from UserState
select * from RoleInf
select * from UserInf
GO
drop table UserState
drop table RoleInf
drop table UserInf

--練習部分,向UserState、RoleInf表中插入新的資料,分別是用戶狀態資料和用戶資料
insert into UserState values ('已審核')
insert into UserState values ('被屏蔽')
insert into RoleInf values ('普通會員','','0.9')
insert into RoleInf values ('VIP會員','','0.8')
insert into RoleInf values ('超級管理員','','0.7')

--用戶表添加一個新資料用于//測驗資料
insert into UserInf values ('大神','84000508','胡偉','1','420621198909193414','[email protected]','','','1000',1,1,'d:\prt\images\Micky.jpg')
select * from UserInf
delete from UserInf where username='大神'
--審核用戶大神//把大神的UserState值修改成2('已審核')
update UserInf set Userstateid=2 where username='大神'


---------------------------檢查用戶是否已審核,如果是已審核用戶把用戶userroleid改成普通會員
declare @count int
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
select @count=COUNT(*) from userinf where username=@username and
[password]=@pwd and userstateid=2
if(@count>0)
begin
update UserInf set Userroleid=2 where username='大神'
print'登陸成功!歡迎'+@username+'您已經通過審核,已經成為普通會員'
end
else
print'登陸失敗'
go


--階段2
---------------------------IF ELSE和WHILE流程控制陳述句
create table CardType(
Id int identity(1,1) primary key,
CardtypeName varchar(20),
ImageUrl nvarchar(100),
Price money
)
create table CardState(
Id int identity(1,1) primary key,
cstate varchar(20)
)
create table CardInf(
CardNo varchar(20),
CardPwd varchar(20),
CardtypeId int foreign key references CardType(Id),
CardStateId int foreign key references CardState(Id),
CardDesc varchar(100),
validityTime datetime
)
drop table CardInf
drop table CardType
drop table CardState


select * from CardState
select * from CardType
select * from Cardinf


--添加游戲卡狀態和分類
GO
declare @stateid int=1
declare @cardtype1 int,@cardtype2 int,@cardtype3 int,@cardtype4 int
declare @cnt int=0

insert into cardstate values('未售出')
--保存Id在后續代碼中使用
set @stateid=@@identity
PRINT '此時 CardState 標識列ID為:@stateid = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardstate values('已售出')
insert into CardType values('泡泡堂游戲卡','',100)
set @cardtype1=@@identity
PRINT '此時 CardType 標識列ID為:@cardtype1 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardtype values('傳奇游戲卡','',50)
set @cardtype2=@@IDENTITY
PRINT '此時 CardType 標識列ID為:@cardtype2 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardtype values('冒險島游戲卡','',150)
set @cardtype3=@@IDENTITY
PRINT '此時 CardType 標識列ID為:@cardtype3 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

insert into cardtype values('英雄聯盟游戲卡','',200)
set @cardtype4=@@IDENTITY
PRINT '此時 CardType 標識列ID為:@cardtype4 = ' + CONVERT(VARCHAR(20), @@IDENTITY)

--游戲卡批量添加,每種型別的卡添加10張
GO
declare @seed nvarchar(8)='84000508'
declare @cnt int=0
declare @stateid int=1
if(@@ERROR=0)--沒有任何錯誤
begin
while(@cnt<50)--回圈添加卡
begin
insert into cardinf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+Convert(nvarchar(2),@cnt),--把@cnt=1 int型別轉換成nvarchar格式之后與@seed nvarchar格式拼接
CONVERT(nvarchar(2),@cnt)+@seed,--把@cnt=1 int型別轉換成nvarchar格式之后與@seed nvarchar格式拼接
5,--魔獸世界卡型別
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
while(@cnt<100)--回圈添加卡
begin
insert into CardInf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+CONVERT(nvarchar(2),@cnt),
CONVERT(nvarchar(2),@cnt)+@seed,
6,--誅仙游戲卡
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
while(@cnt<150)--回圈添加卡
begin
insert into CardInf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+CONVERT(nvarchar(4),@cnt),
CONVERT(nvarchar(4),@cnt)+@seed,
7,--天堂游戲卡
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
while(@cnt<200)--回圈添加卡
begin
insert into CardInf(cardno,cardpwd,cardtypeid,cardstateid,validitytime)
values(
@seed+CONVERT(nvarchar(4),@cnt),
CONVERT(nvarchar(4),@cnt)+@seed,
8,--NBA籃球卡
@stateid,--未出售
'2016-1-1'
)
set @cnt+=1
end
end
GO

select * from CardState
select * from CardType
select * from CardInf


--練習部分,需求說明:
--實作添加用戶投訴功能(只有登陸后的用戶才能投訴)
--實作思路,
--首先必須確定用戶是否可以登錄(參考指導部分代碼),當用戶成功登陸以后,就可以進行投訴,用戶投訴就是向表中Advice中寫入資料,
create table Advice(
Id int identity(1,1) primary key,
UserName nvarchar(20),
Content nvarchar(100)
)
declare @cnt int
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
select @cnt=COUNT(*) from UserInf where username=@username and [password]=@pwd and userstateid=2
if(@cnt>0)
begin
print '登陸成功!歡迎'+@username
insert into Advice values (@username,'為什么,這破游戲還在運營,早點關門吧')
end
else
print '登陸失敗!'

GO
select * from advice


--階段3
---------------------------IF ELSE和WHILE流程控制陳述句
/*
使用if else 陳述句控制流程
使用while陳述句回圈執行sql
使用case-end陳述句進行分支判定
需求說明
實作普通會員和VIP會員的購卡功能
1,需要先確保登陸成功(即用戶名和密碼正確,并且是已經審核用戶)
2,需要檢查賬戶是否有足夠的余額,并且檢查需要購買的游戲卡狀態是否未售出
3,購買時需要一句不同角色計算出實際金額
4,將購買的游戲卡存入購物車表和購物歷史表中
實作思路
若要購卡必須先登錄,登陸時就可以確定角色,保存到區域變數中,在購卡時依據其角色確定不同的則扣,
購卡時要先驗證用戶的賬戶余額,然后驗證游戲卡狀態,將選擇的卡放入購物車,保存到ShoppingCard表中,并記錄到購卡歷史表ShopHistory中,
實作步驟
(1),新建查詢,保存為Chap2-3.sql
(2),在Chap2-3.sql中撰寫T-sql代碼,根據用戶名就,密碼,用戶狀態ID查詢資料行將查詢的資料行賦值給區域變數@cnt
代碼
登陸
*/
--新建ShopHistory和shoppingCart表
create table ShopHistory(
Id int identity(1,1) primary key,
UserName nvarchar(50),
CardNo nvarchar(50),
ShopTime datetime
)
create table shoppingCart(
Id int identity(1,1) primary key,
UserName nvarchar(50),
CardTypeId int,
Num int
)

select * from ShopHistory
select * from shoppingCart

--用戶表
select * from UserState
select * from RoleInf
select * from UserInf
--游戲卡
select * from CardState
select * from CardType
select * from Cardinf

--------------------------------購卡代碼START
go
declare @cnt int=0
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
declare @roleid int
declare @stateid int=2
select @cnt=COUNT(*) from UserInf where username=@username and [password]=@pwd and UserStateId=@stateid--根據用戶名就,密碼,用戶狀態ID查詢資料行將查詢的資料行賦值給區域變數@cnt

--(3)根據變數@cnt是否大于0判斷用戶能否登陸成功,如果登陸成功,還要判斷此用戶的賬戶余額是否足夠購買兩張'魔獸世界游戲卡'
--代碼(接上一代碼)
if(@cnt>0)
begin
print @username+'您好!'
print'1.登陸成功!'
--開始購卡(購買兩張魔獸世界游戲卡)
--檢查賬戶是否有足夠的余額,還要檢查要購買的游戲卡狀態是否為未售出
declare @balance money --保存賬戶余額
select @balance=balance from UserInf where UserName=@username--獲取用戶的余額
select @roleid=UserRoleid from UserInf where Username=@username--獲取用戶的會員級別
declare @requiremoney money--保存需要用掉的金額
declare @dicount decimal(10,2)--不同角色的則扣
select @dicount=discount from RoleInf where Id=@roleid--根據會員級別獲取打折率
--魔獸世界游戲卡型別ID為1
select @requiremoney=@dicount*price*2 from CardType where Id=1--獲取需要用掉的金額
if(@balance>=@requiremoney)--如果用戶賬戶金額>=需要用掉的金額
begin
print'2.開始買卡!'
--滿足了余額要求,再檢查游戲卡狀態
declare @state int--用于檢查游戲卡狀態變數
select @state=CardStateid from Cardinf where CardNo='200301452'--檢查游戲卡的狀態

if(@state=1)--如果游戲卡的狀態為未出售
begin
print'3.點卡200301452未出售!'
select @state=CardStateid from CardInf where CardNo='200301453'--檢查游戲卡的狀態

if(@state=1)
begin
print'4.點卡200301453未出售!'
--購卡成功,添加資料到兩張表
insert into ShopHistory values (@username,'200301452',GETDATE())
insert into ShopHistory values (@username,'200301453',GETDATE())
insert into shoppingCart values (@username,1,2)

if(@@ERROR=0)
begin
print'5.成功添加資料到ShopHistory和shoppingCart!'
update CardInf set cardstateid=2 where cardno in ('200301452','200301453')
update UserInf set Balance -= @requiremoney where username=@username
if(@@ERROR=0)
begin
print'6.購卡成功!更新CardInf和UserInf,完成扣費和卡狀態更新已售出'
end
end
end
end
end
else
print @username+',您的賬戶余額不足,請在線充值'
end
go
--------------------------------購卡代碼END
--執行完畢后,檢查表shoppingcart,shophistory,userinf,cardinf的資料
select * from CardInf
select * from UserInf
select * from ShopHistory
select * from shoppingCart
--------------------------------------------

---------------------------上機作業
/*
1,添加一個管理員賬戶,用戶名為'admin',密碼為'admin123'
2,用戶tom123回款500元
3,匯款經過管理員admin審核以后可以使用
4,匯款狀態有3種:待審核,已審核,掛起
實作思路
先添加匯款狀態和管理員賬號
*/
create table ApproveState(
Id int identity(1,1),
[State] nvarchar(50)
)
create table PostRecord(
Id int identity(1,1) primary key,
UserName nvarchar(20),
Bank nvarchar(50),
[Money] money,
PostTime datetime,
PostDesc nvarchar(225),
ApproveStateId int
)
------------添加匯款狀態------------
declare @state1 int,@state2 int,@state3 int
insert ApproveState values('待審核')
set @state1=@@IDENTITY
insert ApproveState values('已審核')
set @state2=@@IDENTITY
insert ApproveState values('掛起')
set @state3=@@IDENTITY
------------添加管理員------------
declare @admin nvarchar(20)='admin'
declare @adminpwd nvarchar(20)='admin123'
insert into UserInf values(@admin,@adminpwd,'胡偉',1,'420621198909193414','[email protected]','','',888888,2,4,'')
------------匯款審核------------
go
declare @username nvarchar(20)='大神'
declare @pwd nvarchar(20)='84000508'
declare @stateid int=2
declare @money money=500
declare @cnt int=0
declare @id int
select @cnt=count(*) from UserInf where username=@username and [password]=@pwd and UserStateId=@stateid
if(@cnt>0)
begin
print '登陸成功!歡迎'+@username
insert into PostRecord values (@username,'中國工商銀行',@money,GETDATE(),'購買魔獸世界游戲卡','')
set @id=@@identity
if(@@ERROR=0)
begin
print'向PostRecord表中插入購買資訊成功,等待審核!'
update PostRecord set ApproveStateId= 2 where Id=@id
if(@@ERROR=0)
begin
print'審核成功!正在轉賬到賬戶中!'
update UserInf set Balance += @money where UserName=@username
if(@@ERROR=0)
begin
print'充值成功!'
select balance as 您當前金額 from UserInf where username=@username
end
end
end
end
else
print'登陸失敗!'+@username+'請核實再登陸'
go
select * from PostRecord
select * from UserInf
select * from ApproveState
--------------------------------------------------------------------------------深入SQL高級子查詢

use HR
select * from Employee
select * from Salary
select * from Expertise
select * from Department

--查詢編號為'E001'的員工屬于同一個部門的員工
--使用變數方法
declare @deptno nvarchar(10)--定義一個變數記錄部門
select @deptno=DeptNo from Employee where EmpNo='E001'
select * from Employee where DeptNo=@deptno and EmpNo <> 'E001'--查找這個部門的所有員工資訊除了'E001'工號
--使用子查詢
select * from Employee where deptno=(select deptno from Employee where EmpNo='E001') and EmpNo<>'E001'

--查詢工資在5000元以上,并且擁有的技能等級最高的員工資訊
--這個查詢涉及Employee,Salary,Expertise

--1.查詢工資大于5000的員工工號
select EmpNo from Salary where salary>5000

--2.根據1查村出最高技能等級
select MAX(SkillLevel) from Expertise where EmpNo in (select EmpNo from Salary where salary>5000)

--3.根據2查詢出此員工工號
select Empno from Expertise where SkillLevel=(select MAX(SkillLevel) from Expertise where EmpNo in (select EmpNo from Salary where salary>5000))

--4.根據3查詢出此員工資訊
select * from Employee where Empno=(select Empno from Expertise where SkillLevel=(select MAX(SkillLevel) from Expertise where EmpNo in (select EmpNo from Salary where salary>5000)))

---------------------------------------------UPDATE,DELETE,INSERT陳述句中使用子查詢
--1,在update陳述句中使用查詢
select * from Department
select * from Employee
select * from Expertise
select * from Salary

--查詢'E010'所在的部門
select DeptNo from Department where Principal='E010'

--查詢和'E010'在同個部門的員工
select EmpNo from Employee where DeptNo=(select DeptNo from Department where Principal='E010')

--根據員工編號更新技能等級
update Expertise set SkillLevel+=1 from Expertise where EmpNo in (select EmpNo from Employee where DeptNo=(select DeptNo from Department where Principal='E010'))

--2,在Delete陳述句中使用查詢

--查詢技術部所在的部門
select DeptNo from Department where DeptName='技術部'

--根據部門查詢所有員工的工號
select EmpNo from Employee where DeptNo=(select DeptNo from Department where DeptName='技術部')

--查詢準備洗掉的這些資料
select * from Salary where EmpNo in (select EmpNo from Employee where DeptNo=(select DeptNo from Department where DeptName='技術部')) and DATEDIFF(YYYY,StartTime,'2014-10-10 00:00:00')>=5

--最后洗掉這個資料
delete from Salary where EmpNo in (select EmpNo from Employee where DeptNo=(select DeptNo from Department where DeptName='技術部')) and DATEDIFF(YYYY,StartTime,'2014-10-10 00:00:00')>=5

---------------------------------------------在INSERT陳述句中使用子查詢
--基本語法: INSERT INTO 表名(欄位串列) SELECT 欄位串列 FROM 表名
--根據其它表的資料插入到被插入的表中,要求被插入的表必須存在

--備份整個表語法: select * into EmpHistory from Employee

--備份表結構: select * into EmpHistory from Employee where 1<>1
--備份表結構: select top 0 * into EmpHistory from Employee

--使用 insert into 被插入表 子查詢陳述句 where 條件 功能備份資料,要求被插入的表必須存在
--使用 select * into 被插入表 from 原表 where 條件 功能備份資料,被插入的表必須不能存在

select * from Employee
select * from EmpHistory

--(1)備份表結構
select * into EmpHistory from Employee where 1<>1

--(2)使用子查詢將表Employee中的3個離職員工資訊添加到表EmpHistory
--使用 insert into 被插入表 子查詢陳述句 where 條件 功能備份資料,要求被插入的表必須存在
insert into EmpHistory select * from Employee where EmpNo in ('E002','E003','E008')

--使用 select * into 被插入表 from 原表 where 條件 功能備份資料,被插入的表必須不能存在
select * into EmpHistory from Employee where EmpNo in ('E002','E003','E008')

--(3)從員工技能表和員工表中洗掉這3個已經離職的員工資訊
delete from Employee where EmpNo in ('E002','E003','E008')
delete from Expertise where EmpNo in ('E002','E003','E008')

select * from Employee
select * from Expertise


---------------------------------------------高級子查詢陳述句
/*---------------------使用IN,NOT IN的子查詢
當子查詢與比較運算一起使用時,要求子查詢回傳的結果必須是一行記錄或空記錄,
如果子查詢回傳的結果是多行,可以將比較運算子改為IN,IN后面的子查詢允許回傳多行記錄,用于從一個范圍來限制主查詢條件
*/
--1查詢技能的級別在3級以上的員工資訊

select * from Employee where empno in (select EmpNo from Expertise group by EmpNo having MAX(SkillLevel)>=3)

--2洗掉Phone表中重復的資料
select * from Phone

--按Phone,OfficeCode分組(多列分組)
--查詢出經過多列分組之后Id較大的資料//指最新資料
select MAX(Id) from Phone group by Phone,OfficeCode
--洗掉資料不包括分組之后Id較大的資料//指最新資料
delete from Phone where id not in (select MAX(Id) from Phone group by Phone,OfficeCode)


select * from EmpHistory
select * from TimeWork
select * from Employee

--查詢考情表中有但員工表中沒有的記錄
select * from TimeWork where EmpNo not in (select empno from Employee where Employee.EmpNo=TimeWork.EmpNo)

--查詢員工表中所有員工編號
select empno from Employee group by empno
--查詢考情表中有但員工表中沒有的記錄
select * from TimeWork where EmpNo NOT IN (select empno from Employee group by empno)


--查詢技術部有哪些員工
select * from Department
select * from Employee
--
select * from Employee where exists (select * from Department where Department.DeptNo=Employee.DeptNo and DeptName='技術部')--相關子查詢

select * from Employee where DeptNo=(select DeptNo from Department where DeptName= '技術部')--獨立子查詢

select * from (select EmpNo,EmpName,Empaddress,Empphone,Birthday,Hiredate,Employee.DeptNo,Officecode,DeptName,Principal from Employee left join Department on Employee.DeptNo=Department.DeptNo) as ED where DeptName='技術部'--獨立子查詢

select EmpNo,EmpName,Empaddress,Empphone,Birthday,Hiredate,Employee.DeptNo,Officecode from Employee join Department on Department.DeptNo=Employee.DeptNo and DeptName='技術部'

---------------------使用exists,not exists的子查詢
--exists與子查詢在一起使用,用來對子查詢的查詢結果進行存在的測驗,只要子查詢的結果有一個行或者一行以上的資料就回傳真,否則回傳假,
-- 因為結果只取決于是否回傳行,而不取決于這些行的內容,所以exists查詢的條件子查詢輸出串列通常是無關緊要的,只要有一個欄位即可,

--查找出具有C#技能的員工,并顯示詳細資訊

select * from Employee
select * from Expertise
select * from Skill

select * from Employee where exists (select * from Expertise where Expertise.EmpNo=Employee.EmpNo and SkillId=(select SkillId from Skill where SkillName='C#'))


---------------------使用ALL的子查詢
/*
通過比較運算子將一個運算式的值或列值與子查詢回傳的一列值中的每一行進行對比
*/
select * from Salary
select * from Department
/*
分析
1.先查詢select Principal from Department,從部門表中查詢出所有部門負責人的編號
2.再查詢select Salary from Salary where EmpNo in(select Principal from Department),從工資表中查詢出所有的部門負責人的工資
3.執行整個查詢陳述句,Salary表中的salary列的資料依次和(部門負責人的工資)列資料進行對比,滿足條件的篩選出來
*/
select EmpNo , Salary
from Salary
where Salary > all(select Salary from Salary where EmpNo in(select Principal from Department))

---------------------使用ANL/SOME的子查詢
/*
ANY與子查詢在一起使用時,按照比較運算子,運算式或欄位對子查詢的結果每一行進行依次計算和比較,
*/
--查詢只要員工工資大于任何一個部門負責人,就顯示這些員工的資訊
select EmpNo, Salary
from Salary
where Salary > some (select Salary from Salary where EmpNo in (select Principal from Department)) and EmpNo not in (select Principal from Department)

select EmpNo , Salary
from Salary
where Salary > (select MIN(Salary) from Salary where EmpNo in (select Principal from Department)) and EmpNo not in (select Principal from Department)


---------------------使用別名的相關子查詢//沒有懂
select * from Salary
select EmpNo from Salary

select * from Expertise
select empNo from Expertise

select * from Employee
select empNo from Employee

select * from Employee e join Expertise p on e.EmpNo=p.EmpNo

select * from Salary s join Employee e on e.EmpNo=s.EmpNo

--=要求查詢在員工表與技能表中都存在,并且月工資為5000元的一個員工,這個查詢會涉及到3張表:Employee,Expertise,Salary
--57頁
select distinct e.empno,e.empname
from Employee e join Expertise p on e.EmpNo=p.EmpNo where 5000 in (select Salary from Salary s where e.empNo=s.EmpNo)

--上機階段1
---------------------------使用基本子查詢,in子查詢
/*
訓練內容
使用基本子查詢
1,在update陳述句中使用子查詢
2,在insert陳述句中使用子查詢
3,使用in/not in的子查詢
需求說明
實作用戶“jack123”購卡流程:用戶“jack”想一次購買5張NBA籃球卡,要求實作此用戶的購卡流程,
購買游戲卡需要6步驟:
1,查詢用戶需要購買的卡的型別數量是否充足
2,檢查用戶賬戶的余額是夠足夠購買這些卡
3,將購買的游戲卡保存到購物歷史紀錄中
4,將購買的游戲卡資訊保存到購物車
5,跟新用戶的賬戶余額
6,跟新游戲的狀態
*/

--代碼實作

select * from CardInf
select * from UserInf
select * from shoppingCart
select * from shophistory

--1:查詢用戶需要購買的卡的型別數量是否充足
--說明:檢查可以出售的NBA籃球卡是否夠5張使用子查詢來查詢卡的型別ID和狀態ID
GO
declare @CardTypeName nvarchar(20)='冒險島游戲卡'
declare @UserName nvarchar(20)='葫蘆娃'
declare @cnt int
select @cnt=COUNT(*) from CardInf where CardTypeId=(select id from CardType where CardTypeName=@CardTypeName)
and CardStateId=(select id from CardState where cstate='未售出')
print '游戲卡還有'+convert(nvarchar,@cnt)
if(@cnt>=5)
begin
--2:檢查用戶賬戶的余額是夠足夠購買這些卡
--說明:因為用戶會依據角色有一定的折扣,所以用5張卡的面額乘以折扣率
--2.1:查詢賬戶的余額
declare @balance money,@requiremoney money
select @balance=balance from UserInf where UserName = @UserName
print @UserName+'賬戶的余額'+convert(nvarchar,@balance)
--2.2購買5張卡需要的余額
select @requiremoney=5*price from CardType where Id=(select id from CardType where CardTypeName=@CardTypeName)
print '購買5張卡的價格'+convert(nvarchar,@requiremoney)
--2.3根據會員等級打折
set @requiremoney=@requiremoney*(select discount from RoleInf where id=(select userroleid from userinf where username=@UserName))
print '打折后需要的價格'+convert(nvarchar,@requiremoney)
if(@balance>=@requiremoney)
begin
--3:將購買的游戲卡保存到購物歷史紀錄中
--說明:取出NBA籃球卡的前五張,保存到購卡歷史紀錄中,因為已經購買了游戲卡,在后面的代碼中還要修改其狀態,所以使用table型別的變數進行保存
--3.1:5張卡號后面還要使用,所以保存到變數中
declare @temptable table(id int identity(1,1),CardNo nvarchar(20))
insert into @temptable select top 5 cardno from cardinf
where cardstateid=(select id from cardstate where [cstate]='未售出') and cardtypeid=(select id from cardtype where cardtypename=@CardTypeName)
--3.2:回圈購卡
declare @id int=1
while(@id<=5)
begin
insert into shophistory values(@UserName,(select cardno from @temptable where id=@id),getdate())
set @id+=1
end
--4:將購買的游戲卡資訊保存到購物車
--說明:@@ERROR全域變數等于0,保證了它前面的T-SQL已經正確執行,在insert陳述句中使用了子查詢,查詢出游戲卡的型別,在更新已購買的游戲卡狀態時,
-- 在UPDATE陳述句中也使用了子查詢,批量更新這5條游戲卡的狀態ID為 2 (已售出),變數@temptable保存已經選購的游戲卡的卡號
if(@@ERROR=0)
begin
insert into shoppingcart values(@UserName,(select id from cardtype where cardtypename=@CardTypeName),5)
--4.1:更改游戲卡狀態
update cardinf set cardstateid=2 where cardno in (select cardno from @temptable)
end
--5:更新用戶的賬戶余額
if(@@ERROR=0)
begin
declare @surplus money
update UserInf set balance -= @requiremoney where UserName=@UserName
select @surplus=balance from userinf where UserName=@UserName
print '購買成功!您的賬戶余額為'+convert(nvarchar,@surplus)
end
end
else
print @username+'您的賬戶余額為'++convert(nvarchar,@balance)+',余額不足,請在線充值!'
end
GO
/*練習部分
需求說明
使用子查詢統計在所有已經銷售的游戲卡中滯銷的游戲卡型別,熱銷的游戲卡型別及還沒有銷售量的游戲卡型別,
其總銷量小于10張的為滯銷的游戲卡型別,總銷售量大于1000張的為熱銷的游戲卡型別,總銷售量為0的是沒有銷售量的游戲卡型別
實作思路
以查詢滯銷游戲卡為例:使用group by和having查詢出銷售量小于10的游戲卡型別ID,然后依次作為WHERE條件,使用in與這些結果比較,查詢出游戲卡的類別名稱
*/
select * from CardType
select * from CardInf
select * from ShophiStory
select * from UserInf
select * from ShoppingCart
select * from CardType


update UserInf set balance=10000 where username='葫蘆娃'

select cardtypename from CardType where id =ANY (select c.CardTypeId from ShophiStory s,CardInf c where s.CardNo = c.CardNo group by c.CardTypeId having count(s.CardNo)<10)

use Company_DB
select
*,
'銷售情況'=case
when 銷售數量>=10 then '熱銷'

when 銷售數量>0 then '滯銷'

else '還沒銷售'
end
FROM
(select cardtypename, count(ShophiStory.cardno) as 銷售數量 from CardType,CardInf,ShophiStory
where CardInf.CardTypeId=CardType.id AND CardInf.cardno=ShophiStory.cardno
GROUP by cardtypename) as a



--代碼實作
--查找銷量小于10張的為滯銷卡的名稱
select cardtypename from CardType where id =ANY (select c.CardTypeId from ShophiStory s,CardInf c where s.CardNo = c.CardNo group by c.CardTypeId having count(s.CardNo)<10)

--查找沒有銷售量的游戲卡名稱
select cardtypename from CardType where id in (select c.CardTypeId from CardInf c left join ShophiStory s on s.CardNo = c.CardNo group by c.CardTypeId having COUNT(s.CardNo)=0)


--上機階段2
---------------------------使用相關子查詢,ANY子查詢
/*
訓練內容
使用相關子查詢
1,相關子查詢
2,多表鏈接查詢
3,Any子查詢
需求說明
1,在用戶每次購買游戲卡,系統都應該根據其消費金額為用戶升級(指角色升級),
角色級別越高,用戶則扣越高,要求實作用戶角色升級功能,

2,用戶角色升級的條件為:單日消費達到200元或總消費達到1000元時可升一級,
但是最高不能升級成‘超級管理員’,要求分別使用相關子查詢和聯接查詢實作

實作思路
思路一:使用連接查詢
用戶的消費記錄保存在購物歷史紀錄表ShophiStory中,用戶購買的型別不同,價格就不同所以要聯接表CardType查詢價格,
同時,要統計用戶每天購卡的金額就必須根據不同型別的卡將每日購買的金額進行分組統計,
因為單張卡的型別ID在表CARDINF中所以必須與表CARDINF做聯接查詢
思路二:使用相關子查詢
先通過相關子查詢查詢出用戶‘大神’所有買的所有卡的卡號和金額
*/

----------代碼實作
----------相關查詢
/*說明:1,明確外層查詢的表和列
2,明確內層查詢的表和列
3,明確內層查詢與外層查詢的主外鍵關系
4,明確外層查詢的where條件
*/
SELECT
ss.username,
ss.cardno,
ss.shoptime,
(
SELECT price from CardInf ci,CardType ct WHERE ci.cardtypeid=ct.id AND ss.cardno=ci.cardno
)
from ShophiStory as ss
WHERE ss.username = '大神'


SELECT
ShophiStory.username,
ShophiStory.cardno,
ShophiStory.shoptime,
(
SELECT price from CardInf,CardType WHERE CardInf.cardtypeid = CardType.id and CardInf.cardno = ShophiStory.cardno
)
from ShophiStory
WHERE username = '大神'


select
ShophiStory.username,
ShophiStory.cardno,
ShophiStory.shoptime,
(SELECT price from CardInf join CardType on CardInf.CardTypeid=CardType.id and CardInf.cardno=ShophiStory.cardno)
from ShophiStory
where username='大神'


----------連接查詢
select * from ShophiStory
select * from CardInf
select * from CardType

SELECT
ss.username,
ss.cardno,
ss.shoptime,
ct.price
from CardInf ci,CardType ct,ShophiStory ss WHERE ss.cardno=ci.cardno AND ci.cardtypeid=ct.id AND ss.username='大神'


/*實作步驟
方法一:連接查詢實作
*/
--對用戶'葫蘆娃'的角色ID進行升級,按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計),使用any檢查,只要有一天消費金額大于等于200,即可升級,
--獲取管理員的角色ID和當前用戶的角色ID
--代碼實作
use Company_DB
go
--1,查詢用戶當前的角色
declare @role int
select @role=userroleid from UserInf where username='葫蘆娃'--獲取用戶的身份等級
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where rolename <> '超級管理員'--獲取管理員的身份等級
if(@role<@adminrole)--如果用戶的身份等級低于管理員身份
begin

--獲取需要升級的用戶角色等級ID,該角色等級ID是比用戶當前的角色等級ID大的所有的角色等級ID中最小的一個(每次只能升級一級),在第二步的begin與end之間輸入代碼進行判斷
declare @sharprole int -- 需要升級的角色等級ID
select @sharprole=MIN(id) from RoleInf where id > @role --從角色等級表中取出用戶要升級的角色等級ID

--對用戶'葫蘆娃'的角色ID進行升級,按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計),使用any檢查,只要有一天消費金額大于等于200,即可升級,
-- 在第三步的基礎上繼續輸入更新用戶角色的代碼:
--聯接查詢方法實作;
update UserInf
set userroleid=@sharprole
where username='葫蘆娃' and
200 < any
(select SUM(ct.price) as '每日消費' from ShopHistory s,CardInf ci,CardType ct where s.CardNo=ci.cardno and ci.cardtypeid=ct.id and s.UserName='葫蘆娃'
group by CONVERT(char(10),s.ShopTime,120))--把datetime型別轉換成char型別保yyyy-mm-dd

if(@@ERROR=0)--執行未出錯
print 'OK'
end
go

--按用戶消費金額的總額進行升級(總消費滿1000元即可升級),
use Company_DB
go
declare @role int
select @role=userroleid from UserInf where UserName ='葫蘆娃'
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where RoleName <> '超級管理員'
if(@role<@adminrole)
begin
declare @sharprole int
--要升級到角色,一次只能升級一次
select @sharprole=MIN(id) from RoleInf where Id > @role
update userinf
set UserRoleId=@sharprole
where UserName='葫蘆娃'
and (select SUM(ct.Price) as '總消費' from ShopHistory s,CardInf ci,CardType ct where s.CardNo=ci.CardNo and ci.CardTypeId=ct.Id and s.UserName='葫蘆娃')>=1000
if(@@ERROR=0)--執行未出錯
print 'OK'
end
go

/*
方法二:相關子查詢實作
*/
--對用戶'葫蘆娃'的角色ID進行升級,按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計)
--獲取管理員的角色ID和當前用戶的角色ID

--思路參考代碼:!!!
--查詢括號中的類容是關鍵 他通過CardInf表與CardType表進行聯接,然后與外部的ShopHistory表進行逐步行篩選(相關子查詢),查詢的結果作為一個獨立值,其別名為sumPay
select
SUM(re.sumPay) sum_pay
from
(select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃') as re
group by
CAST(CAST(year(re.shoptime)as varchar)+'-'
+CAST(month(re.shoptime)as varchar)+'-'
+CAST(day(re.shoptime)as varchar)as datetime)

select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃'

--思路細節:!!!
select price from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id

select * from CardInf as ci, CardType as ct,ShopHistory as s where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo and s.UserName='葫蘆娃'

select SUM(price) from CardInf as ci, CardType as ct,ShopHistory as s where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo and s.UserName='葫蘆娃'

select SUM(price) from CardInf as ci, CardType as ct,ShopHistory as s where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo and s.UserName='葫蘆娃' group by CONVERT(char(10),s.ShopTime,120)

select * from ShopHistory
select * from UserInf
select * from RoleInf
update UserInf set UserRoleId=1 where UserName='大神' or UserName='葫蘆娃'

--代碼實作
----按照用戶每日購卡消費金額的合計(每日的合計,不包括全部的合計)
use Company_DB
go
declare @role int
select @role=userroleid from UserInf where UserName='葫蘆娃'
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where RoleName <> '超級管理員'
if(@role<@adminrole)
begin
declare @sharprole int
--要升級成的角色
select @sharprole=MIN(id) from RoleInf where Id>@role
update userinf set userroleid = @sharprole
where username='葫蘆娃'
and 1000 < any
(select SUM(re.sumPay) sum_pay
from
(select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃') as re
group by
CAST(CAST(year(re.shoptime)as varchar)+'-'
+CAST(month(re.shoptime)as varchar)+'-'
+CAST(day(re.shoptime)as varchar)as datetime))
if(@@ERROR=0)
print 'ok'

end
go

----按用戶消費金額的總額進行升級(總消費滿1000元即可升級),
use Company_DB
go
declare @role int
select @role=userroleid from UserInf where UserName='葫蘆娃'
declare @adminrole int
select @adminrole=MAX(id) from RoleInf where RoleName <> '超級管理員'
if(@role<@adminrole)
begin
declare @sharprole int
--要升級成的角色
select @sharprole=MIN(id) from RoleInf where Id>@role
update userinf set userroleid = @sharprole
where username='葫蘆娃'
and 1000 < any
(select SUM(re.sumPay) sum_pay
from
(select
s.UserName,
s.CardNo,
s.ShopTime,
(
select SUM(price) from CardInf as ci, CardType as ct where ci.CardtypeId=ct.id and ci.CardNo=s.CardNo
) as sumPay
from
ShopHistory as s where s.UserName='葫蘆娃') as re)
if(@@ERROR=0)
print 'ok'
end
go



--------------------------------------------------------------------------------函式和存盤程序
/*
1、函式
定義:一種封裝一潭訓多條SQL陳述句的結構
好處:
減少代碼冗余,提高代碼重用性
預編譯的,提高代碼執行效率
分類:
聚合函式、系統函式、自定義函式(標量值函式 和 表值函式)
標量值函式:回傳值為一個資料
語法:
create function 函式名
(
引數1 型別,引數2 型別,......引數n 型別
)
returns 回傳值型別
as
begin
函式體
return 值
end
表值函式:回傳值為一個資料表
分類:多陳述句表值函式和行內表值函式
多陳述句表值函式:
語法:
create function 函式名
(
引數1 型別,引數2 型別,......引數n 型別
)
returns 回傳值 table(表結構)
as
begin
函式體
return
end
行內表值函式:
語法:
create function 函式名
(
引數1 型別,引數2 型別,......引數n 型別
)
returns table
as
return (查詢)
*/

---------------------------5.1.2標量值函式
/*
標量值函式的回傳值是基本資料型別的單個值或單個值得運算式,函式體既可以是一條陳述句(可以省略begin end),
也可以是多條陳述句(多條陳述句必須放在begin end之間)
標量值函式可以被另外的標量值函式或表值函式呼叫
*/
--5.1函式的功能是通過引數傳入員工的編號,回傳該員工的工資標準
use HR
go
create function getEmpSalary( @empno varchar(20) ) --引數
returns money --回傳值型別
begin
declare @salary money; --最新工資資料
select @salary=Salary from Salary where Salary = (select top 1 Salary from Salary where EmpNo=@empno order by StartTime desc)
return @salary --回傳值
end
go

--5.2直接輸出標量值函式的回傳值
go
select dbo.getempsalary('E006') as 員工E006的工資標準
go

--5.3將標量值函式的回傳值存入變數
declare @salary money
select @salary = dbo.getEmpSalary('e006')
print '員工E006的月薪是'+convert(varchar(10),@salary)

--5.4新創建函式getDateMaxSlary,在該函式中呼叫示例5.1中創建的getEmpSalary,用來統計一個部門的最高月薪
use HR
go
create function getDeptmaxsalary(@deptno varchar(10)) returns money --定義函式名稱和形參變數
as
begin declare @maxsalary money=0 --定義保存部門的最高月薪
/*因為一個部門有多少員工,使用個基本型別的變數無法保存這些員工的編號,所以使用table型別的變數臨時保存*/
declare @emp table(id int identity(1,1),empno varchar(10))
--將這個部門的員工編號保存到table型別的變數中
insert into @emp select empno from employee where deptno=@deptno
declare @cnt int = 0,@i int=0 --回圈變數
declare @empno varchar(10) --保存員工編號
declare @salary money --保存員工工資
select @cnt=count(*) from @emp --確定回圈次數,查新新臨時表中有幾條資料
while(@i<@cnt)
begin
--查詢每個員工的編號
select @empno=empno from @emp where id=(@i+1)
--呼叫自定義的標量值函式計算當前員工的工資標準
select @salary=dbo.getempsalary(@empno)
if(@salary>@maxsalary)
begin
set @maxsalary=@salary --將最高的工資保存到變數@maxsalary中
end
set @i+=1
end
return @maxsalary
end --回傳最高工資
go

--5.5傳入部門編號呼叫改方法
select * from Department
use HR
go
select dbo.getDeptmaxsalary('d03') as 最高工資
go


---------------------------5.1.3表值函式
--1,多陳述句表值函式
--多陳述句表值函式要求回傳型別為table型別
--需求:回傳所有員工的當前工資標準
use HR
go
--函式執行完畢后回傳table型別的變數@salarytable
create function getEmployeesSalary()
returns @salarytable table(
id int,
EmpNo nvarchar(20),
Salary money,
StartTime datetime
)
as
begin
--為table型別的變數賦值 insert into @salarytable
insert into @salarytable
select * from Salary where StartTime in (select MAX(StartTime) from Salary group by EmpNo)
return --無需再寫值或運算式,直接回傳變數@salarytable
end
go

--使用getEmployeesSalary表值函式
select * from dbo.getEmployeesSalary()
--使用原表salary
select * from Salary


--5.8帶引數的表值寒素
--需求:通過傳入部門編號,回傳指定部門所有員工的當前工資標準
use HR
go
--引數要求傳入的是部門編號
create function getEmpSalaryByDept(@deptno varchar(20))
returns @salarytable table
(
id int,
EmpNo nvarchar(20),
Salary money,
StartTime datetime
)
as
begin
--在子查詢中使用到引數@deptno
insert into @salarytable --查詢最新入職時間 --查找對應部門的員工編號 --按員工分組
select * from salary where starttime in (select max(starttime) from salary where empno in (select empno from employee where deptno=@deptno) group by empno)
return
end
go


--5.9行內表值函式
--根據傳入的引數回傳員工的技能
use HR
go
create function getEmpertiseByEmp(@empno varchar(10))
returns table
as return (select * from Expertise where EmpNo=@empno)
go

select * from getEmpertiseByEmp('e003')
select * from Expertise


----------------------------------------------------存盤程序!!!!!!!
--------------------------------------------------------------------------------------------存盤程序!!!!!!!
------------常用的系統存盤程序
use master
go
exec sp_renamedb 'HR','hr_prj' --改變單用戶訪問的資料庫名稱
go
use cardsale --進入到名稱為hr_prj的資料庫下
go
exec sp_databases --回傳當前實體中的所有資料庫的基本資訊
exec sp_tables --查看資料庫hr_prj中可查看物件的串列
exec sp_help employee --查看表employee的所有資訊
exec sp_helpconstraint employee --查看表employee的約束
exec sp_helptext 'dbo.vw_empsalary'--查看識圖vm_empsalary的定義
exec sp_stored_procedures --查看當前資料庫中所有的存盤程序
use master
go
exec sp_renamedb 'hr','HR'--將資料庫名稱更改回來
go


use master
go
--使用系統存盤程序sp_configure啟用高級選項
exec sp_configure 'show advanced options',1
go
reconfigure --重新配置
go
exec sp_configure 'xp_cmdshell',1 --啟用xp_cmdshell擴展程序
go
reconfigure --重新配置
go
exec xp_cmdshell 'mkdir d:\prj' --呼叫dos命令'mkdir'創建作業系統目錄
if(exists(select * from sysdatabases where name='onlineexam'))
drop database onlineexam
go
create database OnLineExam
on
(
name='OnLineExam_data',
filename='d:\prj\OnLineExam_data.mdf',
size=5mb
)
log on
(
name='OnLineExam_log',
filename='d:\prj\OnLineExam_log.ldf',
size=5mb
)
go
exec xp_cmdshell 'dir d:\prj\' -- 查看創建資料庫檔案
------------用戶自定義存盤程序
------------------------------1.創建不帶引數的存盤程序
--創建存盤函式程序,顯示HR資料庫中月薪最低的員工
use hr
go
if exists(select * from sysobjects where name='UP_Salary_SelectMinSalary')
drop procedure UP_Salary_SelectMinSalary
go
create proc up_Salary_SelectMinSalary
as
select
empname,
minsal.salary
from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary) as minsal,
Employee
where minsal.EmpNo=Employee.empno
--思路
select MAX(StartTime)from Salary group by EmpNo --查詢記錄員工工資的最后記錄時間
select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo) --查詢工資表,根據每個員工的最后記錄時間
select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary --查詢最低工資和員工號
select * from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary) as minsal,Employee where minsal.EmpNo=Employee.empno --聯接查詢最低工資員工的資訊
select empname,minsal.salary
from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in (select MAX(StartTime)from Salary group by EmpNo))as sal order by sal.salary) as minsal,Employee where minsal.EmpNo=Employee.empno --聯接查詢最低工資員工的工資和姓名
--執行存盤程序,查詢工資最低的員工
use hr
go
exec UP_Salary_SelectMinSalary
------------------2.創建帶引數的存盤程序
--創建測驗表
create table timework(
empno nvarchar(20),
[state] nvarchar(20),
dtime datetime
)
use hr
go
if exists(select * from sysobjects where name='UP_TimeWork_Insert')
drop procedure UP_TimeWork_Insert
go
create proc UP_TimeWork_Insert
(
--輸入引數串列
@empno varchar(10), --傳入的員工編號
@state nvarchar(20), --傳入的作業狀態
@dtime datetime --傳入的作業日(注意:最后一個引數不能有逗號)
)
as
--存盤程序執行添加資料(形參串列)
insert into timework values(@empno,@state,@dtime)
if(@@ERROR=0)
print 'ok'
else
print 'error'
go
exec UP_TimeWork_Insert 'E005','休假','2010-1-1'
go
--查詢結果
select * from timework
------------------------3.帶輸出引數的存盤程序
--如果需要存盤程序回傳一個值或者多個值,可以使用輸入引數,輸出引數必須在存盤程序定義時使用output關鍵字進行宣告
--存盤程序可以通過return回傳值,但一般只是回傳一些執行狀態值
--創建一個帶輸入引數和輸出引數的存盤程序UP_Salary_Insert,當使用輸入引數執行添加一條工資標準后,再通過輸出引數回傳工資表中最高工資的員工
use Company_DB
go
if exists(select * from sysobjects where name='UP_Salary_Insert')
drop procedure UP_Salary_Insert
go
create proc UP_Salary_Insert
(
@maxsalary money output, --傳出引數,最高工資標準
@empname nvarchar(20) output, --傳出引數,工資最高的員工姓名
@empno nvarchar(10),
@salary money=10000,
@stime datetime
)
as
insert into Salary values(@empno,@salary,@stime)
--為傳出引數賦值
select @empname=empname,@maxsalary=maxsal.salary
from
(select top 1 empno,sal.Salary as salary from (select * from Salary where StartTime in(select MAX(StartTime) from Salary group by EmpNo ))as sal order by sal.Salary desc) as maxsal,Employee
where maxsal.empno=employee.empno
--在呼叫帶傳出引數的存盤程序時,需要先定義對應的變數作為實際引數,并且在實際引數后面必須使用output關鍵字,
-- 執行存盤程序成功后,就可以通過變數得到存盤程序傳出的引數值
--先定義變數,與傳出引數保持型別一致
declare @maxsal money,@emp nvarchar(20)
--執行存盤程序時,將變數作為實際引數,并使用output關鍵字進行說明
execute UP_Salary_Insert @maxsal output,@emp output,'E011',13000,'2010-01-01'
--執行完畢后,通過變數得到存盤程序傳出的值
print @emp
print '工資'+convert(nvarchar(20),@maxsal)
go
--------------------4.錯誤處理
use Company_DB
go
if exists(select * from sysobjects where name='UP_Salary_Insert')
drop procedure UP_Salary_Insert
go
create proc UP_Salary_Insert
(
@maxsalary money output, --傳出引數,最高工資標準
@empname nvarchar(20) output, --傳出引數,工資最高的員工姓名
@empno nvarchar(10),
@salary money=10000,
@stime datetime
)
as
if(@stime<getdate())
begin
--自定義錯誤,以便執行時獲取詳細的錯誤資訊,錯誤級別15,狀態1為默認值
raiserror('新的工資標準執行日期必須大于當前日期',15,1)
return --退出存盤程序的執行
end
insert into salary values(@empno,@salary,@stime)
select @empname=empname,@maxsalary=maxsal.salary
from
(select top 1 empno,Sal.salary as salary from (select * from Salary where StartTime in (select MAX(StartTime) from Salary group by EmpNo)) as sal order by sal.Salary desc) as maxsal,
employee
where maxsal.empno=employee.empno
go
--執行存盤程序,捕獲錯誤
declare @maxsal money=0,@emp nvarchar(20)=''
exec UP_Salary_Insert @maxsal output,@emp output,'e011',8888888888,'2000-01-01'
declare @err int
set @err=@@ERROR
if(@err<>0)
begin
print '錯誤號:'+convert(varchar(10),@err)
return --退出批處理,后續陳述句將不再執行
end
print @emp
print '工資'+ convert(varchar(100),@maxsal)
go
--上機階段1
---------------------------創建和使用標量值函式,創建和使用多陳述句表值函式
/*
指導部分
訓練型別
創建標量值函式
將標量值函式作為列的默認值使用
創建多陳述句表值函式
需求說明
創建標量值函式,完成判斷‘游戲點卡銷售系統’中用戶注冊時間,當注冊時間處于每天的0點到7點是,贈送用戶50元購物卡金額,
在用戶表中添加默認值約束,將函式的回傳值作為新用戶余額的默認值

創建一個多陳述句白哦之函式,完成根據接受的年份回傳此用戶每月的消費金額

實作思路
在標量值函式中徐需要判定系統時間,根據時間回傳不同的值,如果時間在0點到7點之間,就回傳50元,否則回傳0.多陳述句表值函式內,
回傳一個包含用戶名,月份,月消費合計3個列的table型別的資料記錄
*/
--實作步驟
-- 1,無引數的表量值函式,回傳值為money型別
use cardsale
go
create function DefaultMoney()
returns money
as
begin
declare @money money=0
--0點到7點之間
if(datepart(hh,getdate())>=0 and datepart(hh,getdate())<=7)--如果當前時間是在0-7點之間,通過datepart()獲取當前時間的小時
set @money=50
return @money
end
go
--2,使用系統函式檢查函式是否創建成功
execute sp_helptext 'DefaultMoney'
go
--3,使用T-SQL 為UserInf表添加默認值約束
alter table userinf add constraint DF_Balance default(dbo.DefaultMoney()) for Balance
go
--4,呼叫系統存盤程序sp_helpconstraint查看USERINF表的約束,
exec sp_helpconstraint userinf
--5,將計算機系統時間調至0點到7點之間,輸入測驗資料,檢查函式是否能成功作為默認值使用
insert into UserInf
values('測驗001',123456,'程式員',1,'','','','',50,'2','1','')
--6,創建一個標值函式,函式接收一個datetime型別的引數,回傳含有3個欄位的table型別集合,
-- 查詢的時候線通過3張表連接查詢出所有用戶一年年的消費記錄,然后將該結果集作為子查詢,
-- 按用戶的月份進行分組合計
alter function getsalebymonth(@date datetime)
returns @sales table --回傳表值
(
username varchar(20),
smonth int,
amount money
)
as
begin
insert into @sales select uname,MONTH(stime),SUM(price)
from
(select s.UserName uname,s.ShopTime stime,ct.Price price
from ShopHistory s,CardInf ci, CardType ct
where s.CardNo=ci.CardNo and ci.CardTypeId=ct.Id and year(s.ShopTime)=year(@date)) SaleInf
group by uname,MONTH(stime)

return
end
--7,使用select測驗該表值函式
declare @date datetime='2016-8-27' --呼叫函式錢要先宣告變數
select * from getsalebymonth(@date)
/*
練習部分(一)
需求說明:創建一個無引數的存盤程序,呼叫階段1指導部分創建的標值函式,
實作如下業務規則:本年度消費金額滿500元的用戶,回傳購卡金額的10%到用戶賬戶
使用IN
*/
--使用函式進行查詢,查詢結果作為更新的條件
update userinf set Balance=Balance+500 where UserName in
(select distinct username from getsalebymonth(GETDATE())
where amount>=500)
/*
練習部分(二)
需要說明:使用系統存盤程序,將D盤中的兩個檔案1.TXT和2.TXT進行連接,生產一個新的檔案
使用xp.cmdshell
*/
exec sp_configure 'show advanced options',1
execute xp_cmdshell 'copy /b D:\1.txt + D:\2.txt D:\3.txt'
--上機階段2
---------------------------撰寫帶引數的存盤程序,使用系統存盤程序
/*
指導部分:
撰寫帶輸入和輸出的存盤程序
使用系統存盤程序將用戶自定義訊息寫入windows事件查看器
執行存盤程序

需求說明
1,創建存盤程序,實作管理員登錄功能
2,創建存盤程序,要求時間用戶購買游戲卡程序,如果用戶要購買的游戲卡的金額超過了用戶賬戶余額,則引發用戶自定義的錯誤,
并使用系統存盤程序將錯誤寫入到windows時間查看器,完成存盤程序,檢查windows事件查看器中寫入的錯誤資訊

實作思路
實作管理員登錄功能只需要傳入引數,即用戶名和密碼,實作用戶購買游戲卡存盤程序時,如果用戶的余額不足購買游戲卡,則使用
raiserror引發自定義的錯誤,在執行存盤程序后,使用xp_logevent擴展程序將用戶自定義的錯誤號寫入windows事件查看器中

實作步驟
1,創建存盤程序UP_Admin_Login
*/
use Company_DB
go
create proc UP_Admin_Login
(
@uname varchar(20), --輸入用戶名
@pwd varchar(20), --輸入密碼
@tag int output --傳出是否登錄成功的標志(1表示登錄成功 0表示登錄失敗)
)
as
set @tag=0
if((select COUNT(*) from UserInf where UserName=@uname and [password]=@pwd and UserRoleId=4)>0)
begin
set @tag=1
end

-- 2, 執行存盤程序
declare @flag int
exec UP_Admin_Login 'admin','admin123', @flag output
if(@flag=1)
print '管理登錄成功!'
else
print '身份驗證失敗,無法登錄!'
go

-- 3,輸入代碼,創建用戶購買游戲卡的存盤程序
if(exists (select * from sysobjects where name='UP_BuyCard'))
drop proc UP_BuyCard
go
-- 4,創建存盤程序,存盤程序一次購買一張卡,要求輸入卡型別,用戶名,
alter procedure UP_BuyCard
(
@CardtypeName nvarchar(50), --游戲卡名稱
@user varchar(20) --用戶名
)
as
declare @typeid int --卡型別變數
declare @sumerror int=0 --錯誤變數
declare @cnt int --次數變數
select @typeid=id from CardType where CardtypeName=@CardtypeName --根據用戶提供的游戲卡名稱查詢這個游戲的型別ID

select @cnt=COUNT(*) from CardInf where CardtypeId=@typeid --根據游戲的型別ID和游戲卡'未出售'ID查詢這個游戲卡的庫存剩余數量
and CardStateId=(select id from CardState where cstate='未售出')

if(@cnt>=1) --檢查是否有可以售出的卡
begin
declare @balance money,@requiremoney money--宣告變:剩余錢,需要錢
select @balance=balance from UserInf where UserName=@user --根據用戶提供的用戶名查找這個用戶的賬戶余額
select @requiremoney=price from CardType where Id=@typeid --根據游戲要購買的游戲卡的型別ID查詢這個游戲卡的價格
select @requiremoney=@requiremoney*(select discount from RoleInf --根據用戶提供的用戶名查詢這個用戶的身份ID,再根據身份ID查詢則扣率,最后根據則扣率*需要錢,從而查詢出這個用戶購買游戲卡需要花費的錢
where Id=(select UserRoleId from UserInf where UserName =@user))
begin
--開始購卡
begin transaction --開始事物
declare @cardno varchar(20)
--可以出售的某類游戲卡中帳號的一張
select @cardno=MAX(cardno) from CardInf where
CardtypeId=@typeid and CardStateId=(select id from CardState where cstate='未售出')--根據游戲卡型別和游戲狀態查找這類游戲的帳號,找出一張賦值給@cardno變數

insert into shoppingCart values(@user,(select id from CardType where CardtypeName=@CardtypeName),1)
set @sumerror+=@@error
update CardInf set CardStateId=2 where CardNo=@cardno--更新賣出去的這張卡號的狀態
set @sumerror+=@@error --給@sumerror賦值用于查看上一個增刪改操作是否出錯
update UserInf set balance -= @requiremoney where UserName=@user--跟新用戶的錢
set @sumerror+=@@error
if(@sumerror>0)
begin
print 'NO'
rollback transaction--回滾事物
end
else
begin
print 'OK'
commit transaction--提交事物
end
end
end
else
begin
--引發用戶自定義的錯誤
raiserror('賬戶的余額不夠,請及時充值!',16,1)
end
go



declare @err int
exec UP_BuyCard '英雄聯盟游戲卡','我有錢'
set @err=@@ERROR+150505050 --訊息日志中只能寫入訊息號大于50000的訊息
if(@err<>0)
--寫入錯誤資訊到windows訊息日志
execute xp_logevent @err, '賬戶余額不足,請及時充值',informational


--聯系部分

--需求說明
--使用存盤程序實作用戶匯款和用戶投訴功能,要求用戶匯款后立即審核,并將用戶的賬戶余額回傳,匯款銀行使用默認值‘工商銀行’,存盤程序撰寫完畢后,為用戶‘我有錢’匯款1000元
--實作思路
--用戶匯款后要求能夠通知用戶當前的賬戶余額,可以通過傳出引數實作,匯款銀行通過傳入引數添加默認值實作
go
alter procedure UP_Postmonry
(
@user nvarchar(20),
@money money,
@bank nvarchar(20)='工商銀行',
@desc nvarchar(1000),
@balance money output
)
as
begin
--匯款代碼-----------------------------------------------------
--1,判斷用戶的余額是否夠購買游戲卡
declare @err int
select @balance=Balance from UserInf where UserName=@user
if(@balance>=@money)
begin
begin transaction--開始事物
update UserInf set Balance=Balance+@money where UserName='admin'
set @err+=@@ERROR
update UserInf set Balance=Balance-@money where UserName=@user
set @err+=@@ERROR
if(@err > 0)
rollback transaction
else
begin
print '轉賬成功!'
commit transaction
end
end
else
begin
print '您的賬戶余額不足,請及時充值!匯款失敗!'
end

--審核代碼-----------------------------------------------------

--為傳出引數賦值----------------------------------------------
select @balance=Balance from UserInf where UserName='我有錢'
end
go
declare @amount money
--引數@bank沒有傳入具體值,引數使用默認值
execute UP_Postmonry @user='我有錢',@money=1000,@desc='購買天堂游戲卡',@balance=@amount output
print '用戶我有錢的余額是'+convert(nvarchar(20),@amount)
-----------------------------------------------------視頻資料-----------------------------------------------------------------------------------------------------------------------------------------
use PPTDemo
create table Tb_Student(
TId int identity(1,1) primary key,
TGender nvarchar(2),
TSalary money,
TAge int,
TBirthday datetime
)
-----------------------------------------
create table Employees
(
EmpId int identity(1,1),
EmpName varchar(50),
EmpGender char(2),
EmpAge int,
EmpEmail varchar(100),
EmpAddress varchar(500)
)
create table Department
(
DepId int identity(1,1),
DepName varchar(50)
)
select * from Employees
select * from Department
drop table Employees
---------------------------------------手動增加約束
--手動洗掉一列
alter table Employees drop column EmpAddress
--手動增加一列
alter table Employees add EmpAddress nvarchar(1000)
--修改一下EmpEmail的資料型別(varchar(200))
alter table Employees alter column EmpEmail varchar(200)
--為EmpId增加一個主鍵約束
alter table Employees add constraint PK_Employees_EmpId primary key(EmpID)
--非空約束,為EmpName增加一個非空約束(修改列)
alter table Employees alter column EmpName varchar(50) not null
--為EmpName增加一個唯一約束
alter table Employees add constraint UQ_EEmployees_EmpName unique(EmpName)
--為EmpGender增加一個默認約束,默認‘男’
alter table Employees add constraint DF_Employees_EmpGender default('男') for EmpGender
--為EmpGender增加一個檢查約束,要求只能是'男'or'女'
alter table Employees add constraint CK_Employees_EmpGender check(EmpGender='男' or EmpGender='女')
--為年齡增加一個檢查約束;年齡在0-120歲之間
alter table Employees add constraint CK_Employees_EmpAge check(EmpAge>=0 and EmpAge<=120)
--創建一個部門表,然后為Eemployee表增加一個DepId列
alter table Employees add Employees int
--為Department表設定主鍵,主鍵列是:DepId
alter table Department add constraint PK_Department_DepId primary key(DepId)
--增加外鍵約束
alter table Employees add constraint PK_Employees_Department foreign key(EmpDepId) references Department(DepId)
---------------------------------------------------------------------------------------------
-----洗掉約束(多個一起洗掉)-------------------------------------------------------------
alter table Employees drop constraint PK_Employees_EmpId,UQ_EEmployees_EmpName,CK_Employees_EmpAge,CK_Employees_EmpGender,DF_Employees_EmpGender
-----增加約束(多個一起增加)-------------------------------------------------------------
alter table Employees add
constraint CK_Employees_EmpAge check(EmpAge>=0 and EmpAge<=120),
constraint CK_Employees_EmpGender check(EmpGender='男' or EmpGender='女'),
constraint DF_Employees_EmpGender default('男') for EmpGender,
constraint UQ_Employees_EmpName unique(EmpName),
constraint PK_Employees_EmpId primary key(EmpID)
create table Employees
(
EmpId int identity(1,1) identity(1,1) primary key,
EmpName varchar(50) not null unique check(len(EmpName)>2),
EmpGender char(2) default('男'),
EmpAge int check(EmpAge>0 and EmpAge<120),
EmpEmail varchar(100) unique,
EmpAddress varchar(500) not null
EmpDepId int foreign key references Department(DepId) on delete cascade--on delete cascade級聯洗掉
)
--查詢所有行所有列
select * from Employees
--查詢所有行部分列
select EmpId,EmpName,EmpGender from Employees
--查詢部分行所有列(使用where條件篩選部分行顯示)
select * from Employees where EmpAge='20'
--給查詢結果集中的列起別名(只是把當前查詢出來的結果集的列名修改了,對原表沒有修改)
select EmpId as 員工編號,EmpName as 學生姓名,EmpGender as 學生性別 from Employees
select 員工編號=EmpId,學生姓名=EmpName,學生性別=EmpGender from Employees
--給查詢結果集中新增加列
select 員工編號=EmpId,學生姓名=EmpName,學生性別=EmpGender,婚否='' from Employees
/**SELECT不必和FROM配合使用,可以單獨使用
獲取系統當前系統時間
*/
select 當前系統時間=GETDATE()
select GETDATE() as 當前系統時間
select
打野='皇子',
中單='莫干娜',
ADC='女警',
輔助='風女'


------------------------------------------------TOP和DISTINCT---------------------------------
--去除重復失敗,因為有自增主鍵,所以原表資料沒有重讀
select distinct * from Employees
--DISTINCT關鍵字,針對已經查詢出的結果集進行去除重復
--此處的DISTINCT關鍵字的作用是針對select EmpName,EmpGender from Employees查詢結果集去重復,EmpName和EmpGender的值完全一樣,可以成功
select DISTINCT EmpName,EmpGender from Employees
--TOP獲取前幾條資料,TOP一般都與order by一起使用
--TOP
--查詢年齡最高的前5名
select top 5 * from Employees order by EmpAge desc
--如果TOP后面不是數字,而是一個運算式一定要使用()把運算式括起來
select top (5*20) * from Employees order by EmpAge desc
--查詢前分之分30
select top 30 percent * from Employees order by EmpAge desc
--order by 列名
--按照年齡,降序排序
select * from Employees order by EmpAge desc
--按照年齡, 升序排序
select * from Employees order by EmpAge asc--默認升序
------------------------------------------------聚合函式---------------------------------
--統計出所有人的年齡的總和
select SUM(EmpAge) as 年齡的綜合 from Employees
--統計出表中一共有多少條記錄
select COUNT(*) as 一共的記錄 from Employees
--統計出表中所有人的平均年齡(因為整數/整數=整數,為了讓結果成為小數,可以*0.1)
select
(select SUM(EmpAge) as 年齡的綜合 from Employees)*1.0/(select COUNT(*) as 一共的記錄 from Employees) as 平均年齡
from Employees

--年齡最大的
select MAX(EmpAge) from Employees
--年齡最小的
select MIN(EmpAge) from Employees
--計算平均值
select AVG(EmpAge*1.0) from Employees
----------------------------------------------------聚合函式的一些其它的問題------------------------
--1.聚合函式不統計空值
--2.如果使用聚合函式的時候,沒有手動group by分組,那么聚合函式會把整個表中的資料作為一組來統計
select *from Employees
select count(EmpEmail) from Employees

select AVG(EmpAge) from Employees--AVG()也不統計空值

-------------------------------帶條件查詢
--select 列
--from 表
--where 條件
--查詢沒有及格的學生(假設:數學或英語,只要有一門沒有及格就叫沒有及格)的學號
select tSId from TblScore where tEnglish<60 or tMath<60

--查詢年齡在20-30之間的男學生 AND
select * from MySudent where FAge>=20 and FAge <=30 and FGender='男'

--between...and 在....之間(閉區間,包含兩個端點值) BETWEEN
select * from MySudent where FAge between 20 and 30 and FGender='男'

--查詢出所有班級Id為3,4,5的那些學生 OR
select * from MySudent where classid=3 or classid=4 or classid=5
select * from MySudent where classid in(3,4,5)

--對于in或者or查詢,如果查詢中的條件是連續的幾個數字,最好使用>= <=或者between...and 不要使用or或者and
select * from MySudent where classid>=3 and classid<=5

-------------------------------模糊查詢
-- _ 表示任意的當個字符
-- % 表示任意多個任意的字符
-- []表示篩選,范圍



-------------------------------空值處理---------------------------------------------
--null值無法使用=或<>來進行比較

--查詢所有年齡是null的同學資訊
select * from MySudent where Age is null

--查詢所有年齡不是null的同學
select * from MySudent where Age is not null
--任何值與null進行運算,結果還是null
select 2000+null
-----------------------------------執行順序---------------------------------------------
select * --3.
from Score --1.
where english>60 and math>60 --2.
order by english desc,math desc --4.
--------------------------------------GROUP BY---------------------------------------------重點!!!
/*
在使用select查詢的時候,又是需要對資料進行分組匯總(即:將現在有的資料按照某列來匯總統計),這時候就用到GROUP BY陳述句,
select陳述句中可以使用group by字句將行劃分成較小的組,然后,使用聚合函式回傳每一個組的匯總資訊,
分組一般都和聚合函式連用
*/
create table studenttest
(
xh int not null,
xm varchar(10) not null,
xb varchar(2) not null,
km varchar(10) not null,
cj int
)
drop table studenttest
insert into studenttest values(1,'韓曉青','女','C語言',55);
insert into studenttest values(2,'洪少俠','男','C語言',56);
insert into studenttest values(3,'胡友松','男','C語言',57);
insert into studenttest values(4,'蒯衛','女','C語言',58);
insert into studenttest values(5,'雷雨慧','男','C語言',59);
insert into studenttest values(6,'李歡歡','女','C語言',60);
insert into studenttest values(7,'李文杰','男','C語言',61);
insert into studenttest values(8,'劉梅','女','C語言',62);
insert into studenttest values(9,'路俊鵬','男','C語言',63);
insert into studenttest values(10,'呂鋼','男','C語言',64);
insert into studenttest values(11,'潘桂琴','女','C語言',65);
insert into studenttest values(12,'錢歡','男','C語言',66);
insert into studenttest values(13,'邵旭','男','C語言',67);
insert into studenttest values(14,'水玉帥','男','C語言',68);
insert into studenttest values(15,'宋元芬','女','C語言',69);
insert into studenttest values(16,'王斌','男','C語言',70);
insert into studenttest values(17,'聞雪','女','C語言',71);
insert into studenttest values(18,'向瑤','女','C語言',72);
insert into studenttest values(19,'謝守鵬','男','C語言',73);
insert into studenttest values(20,'楊麗敏','女','C語言',74);
insert into studenttest values(21,'楊文財','男','C語言',75);
insert into studenttest values(22,'張紅','女','C語言',76);
insert into studenttest values(23,'張明婷','女','C語言',77);
insert into studenttest values(24,'張鵬宇','男','C語言',78);
insert into studenttest values(25,'張帥','男','C語言',79);
insert into studenttest values(1,'韓曉青','女','JAVA語言',22);
insert into studenttest values(2,'洪少俠','男','JAVA語言',23);
insert into studenttest values(3,'胡友松','男','JAVA語言',24);
insert into studenttest values(4,'蒯衛','女','JAVA語言',25);
insert into studenttest values(5,'雷雨慧','男','JAVA語言',26);
insert into studenttest values(6,'李歡歡','女','JAVA語言',27);
insert into studenttest values(7,'李文杰','男','JAVA語言',28);
insert into studenttest values(8,'劉梅','女','JAVA語言',29);
insert into studenttest values(9,'路俊鵬','男','JAVA語言',30);
insert into studenttest values(10,'呂鋼','男','JAVA語言',31);
insert into studenttest values(11,'潘桂琴','女','JAVA語言',32);
insert into studenttest values(12,'錢歡','男','JAVA語言',33);
insert into studenttest values(13,'邵旭','男','JAVA語言',34);
insert into studenttest values(14,'水玉帥','男','JAVA語言',35);
insert into studenttest values(15,'宋元芬','女','JAVA語言',36);
insert into studenttest values(16,'王斌','男','JAVA語言',37);
insert into studenttest values(17,'聞雪','女','JAVA語言',38);
insert into studenttest values(18,'向瑤','女','JAVA語言',39);
insert into studenttest values(19,'謝守鵬','男','JAVA語言',40);
insert into studenttest values(20,'楊麗敏','女','JAVA語言',41);
insert into studenttest values(21,'楊文財','男','JAVA語言',42);
insert into studenttest values(22,'張紅','女','JAVA語言',43);
insert into studenttest values(23,'張明婷','女','JAVA語言',44);
insert into studenttest values(24,'張鵬宇','男','JAVA語言',45);
insert into studenttest values(25,'張帥','男','JAVA語言',46);
insert into studenttest values(26,'趙恒橋','男','JAVA語言',47);
insert into studenttest values(27,'趙鵬','男','JAVA語言',48);
insert into studenttest values(28,'周亞坤','男','JAVA語言',49);
insert into studenttest values(29,'鄒瑜','男','JAVA語言',50);
insert into studenttest values(30,'左云','女','JAVA語言',51);
insert into studenttest values(31,'大神','女','JAVA語言',51);
insert into studenttest values(1,'韓曉青','女','HTML',52);
insert into studenttest values(2,'洪少俠','男','HTML',53);
insert into studenttest values(3,'胡友松','男','HTML',54);
insert into studenttest values(4,'蒯衛','女','HTML',55);
insert into studenttest values(5,'雷雨慧','男','HTML',56);
insert into studenttest values(6,'李歡歡','女','HTML',57);
insert into studenttest values(7,'李文杰','男','HTML',58);
insert into studenttest values(8,'劉梅','女','HTML',59);
insert into studenttest values(9,'路俊鵬','男','HTML',60);
insert into studenttest values(10,'呂鋼','男','HTML',61);
insert into studenttest values(11,'潘桂琴','女','HTML',62);
insert into studenttest values(12,'錢歡','男','HTML',63);
insert into studenttest values(13,'邵旭','男','HTML',64);
insert into studenttest values(14,'水玉帥','男','HTML',65);
insert into studenttest values(15,'宋元芬','女','HTML',66);
insert into studenttest values(16,'王斌','男','HTML',67);
insert into studenttest values(17,'聞雪','女','HTML',68);
insert into studenttest values(18,'向瑤','女','HTML',69);
insert into studenttest values(19,'謝守鵬','男','HTML',70);
insert into studenttest values(20,'楊麗敏','女','HTML',71);
insert into studenttest values(21,'楊文財','男','HTML',72);
insert into studenttest values(22,'張紅','女','HTML',73);
insert into studenttest values(23,'張明婷','女','HTML',74);
insert into studenttest values(24,'張鵬宇','男','HTML',75);
insert into studenttest values(25,'張帥','男','HTML',76);
insert into studenttest values(26,'趙恒橋','男','HTML',77);
insert into studenttest values(27,'趙鵬','男','HTML',78);
insert into studenttest values(28,'周亞坤','男','HTML',79);
insert into studenttest values(29,'鄒瑜','男','HTML',80);
insert into studenttest values(30,'左云','女','HTML',81);
insert into studenttest values(31,'哈哈','女','HTML',81);
insert into studenttest values(32,'王云','女','HTML',81);
insert into studenttest values(33,'旺財','女','HTML',81);
select * from studenttest
--查詢每個科目的人數
select km,max(xh) as 科目人數 from studenttest group by km
--統計性別人數
select 性別=xb,COUNT(xb) from studenttest group by xb
--統計每個科目男同學的人數,和男同學的平均分
select km,COUNT(*) as 男同學人數,avg(cj) 平均成績 --4
from studenttest --1
where xb='男' --2
group by km --3
--當使用了分組陳述句(group by)或者是聚合函式的時候,在select的查詢串列中不能再包含其他列名,
-- 除了該列同時也出現了group by字句中,或者該列也包含了在某個聚合函式中
-------------------------------HAVING與where-----------------------------
--對分組以后的資料進行篩選:使用having
--對分組以前的資料進行篩選:使用where
select km,COUNT(*) as 男同學人數,avg(cj) 平均成績 --4
from studenttest --1
group by km --2
having avg(cj)>60 --3 -- 因為先執行的having后執行的select所以不可以使用別名,再它之前別名還沒有創建
-- order by可以使用別名,因為order by永遠是最后執行,再它之前別名已經創建好了

---------------------------------型別轉換函式CAST,CONVERT
select '1000'+100
print '1000'+100
select 100.0+'1000'--失敗,將 varchar 轉換為資料型別 numeric 時出現算術溢位錯誤,
select 100.0+CAST('1000' as int)
select 100.0+CONVERT(int,'1000')
select '你的班級編號是:'+1--在將 varchar 值 '你的班級編號是:' 轉換成資料型別 int 時失敗,
select '你的班級編號是:'+CONVERT(nvarchar(1),1)
--TableConvert表中bid列是varchar型別的數字,要求按數字大小排序,需要轉換型別
select * from TableConvert order by CONVERT(int,bid) desc
--轉換時間格式
print convert(varchar(100),getdate(),120)
print convert(varchar(10),getdate(),120)
---------------------------------UNION聯合結果集(集合運算子)---------------------------------
--聯合:指把結果集的行聯合起來 5行+4行 結果集9行
--連接:指吧結果集的列連接起來 3列+4列 結果集7列
select * from TBStudent
union all
select * from MyStudent--聯合不了,因為列數不同,資料型別不兼容
----------------UNION進行聯合,區別在于:使用union聯合會去除重復,從新排列
----------------UNION ON進行聯合,區別在于:不會去除重復也不會從新排列
----------------大多數情況下,聯合的時候不需要去除重復,同時要保持資料的順序,所以一般建議使用 UNION ALL
select tname,tgender,tage from TBStudent
union all
select tname,tgender,tage from MyStudent--可以聯合,列數相同,資料型別兼容(不會去除重復也不會從新排列)
select tname,tgender,tage from TBStudent
union
select tname,tgender,tage from MyStudent--可以聯合,列數相同,資料型別兼容(使用union聯合會去除重復,從新排列)
--查詢出成績表中的:最高分,最低分,平均分
select
MAX(cj) as 最高分,
min(cj) as 最低分,
avg(cj) as 平均分
from studenttest
select
最高分=(select MAX(cj) from studenttest),
低分分=(select MIN(cj) from studenttest),
平均分=(select AVG(cj) from studenttest)
select 名稱='最高分',分數=MAX(cj) from studenttest
union all
select 名稱='最低分',分數=MIN(cj) from studenttest
union all
select 名稱='平均分',分數=avg(cj) from studenttest
-----------------使用UNION一次插入多行資料
SELECT * FROM studenttest
INSERT into studenttest
select '37','大王','男','修仙','500' union all
select '37','觀音','女','修仙','600' union all
select '37','豬八戒','男','修仙','700' union all
select '37','悟空','男','修仙','800'
--在使用union進行插入資料的時候也要注意union會去除重復的,
--下面union插入只會插入4條資料,建議使用union all
INSERT into studenttest
select '37','大王','男','修仙','500' union
select '37','觀音','女','修仙','600' union
select '37','豬八戒','男','修仙','700' union
select '37','悟空','男','修仙','800'union
select '37','大王','男','修仙','500' union
select '37','觀音','女','修仙','600' union
select '37','豬八戒','男','修仙','700' union
select '37','悟空','男','修仙','800'
---------------------------------------向表中插入多條記錄------------------------------
--查詢所有表中所有的資料保存到另外一張表中
--用于備份表
--意思是從studenttest表中查詢資料保存到tempstustudenttest這張表中,如果預先沒有tempstustudenttest這張表,
--當執行insert into陳述句的時候會自動創建tempstustudenttest表,
--tempstustudenttest表結構和studenttest表結構和自動偏好列一樣,但是tempstustudenttest表中沒有studenttest表中的約束
--insert into陳述句不能夠重復執行,因為每次執行都會創建一個tempstustudenttest表
--student
select * into tempstustudenttest from studenttest
--select * from tempstustudenttest
--select * from studenttest
drop table tempstustudenttest
--用于拷貝表結構,不拷貝資料
select * into tempstustudenttest from studenttest where 1<>1
select top 0 * into tempstustudenttest from studenttest
select * from tempstustudenttest
--使用insert into 表 select,,,from 表
--把studenttest表中的資料添加到已有資料的tempstustudenttest表中
select * from tempstustudenttest
insert into tempstustudenttest values(50,'大黃蜂','男','機械化',120);
insert into tempstustudenttest values(55,'機械公敵','男','科技化',250);
insert into tempstustudenttest
select * from studenttest where xb='女'
---------------------------------------常用的字串函式------------------------------
--1.len() 計算字符的個數
print len('我愛你520')
--datalength()回傳所占用的位元組的個數,這個不是字串函式
print datalength('我愛你520')--9
print datalength(N'我愛你520')--12
--2.
print upper('hello world') --轉換大寫
print lower('HELLO WORLD') --轉換小寫
--3.去掉兩段的空格
print '========='+' hello '+' =============='
print '========='+ltrim(' hello ')+' =============='--去掉左邊空格
print '========='+rtrim(' hello ')+' =============='--去掉右邊空格
print '========='+rtrim(ltrim(' hello '))+' =============='--去掉兩段的空格
--4.字串的截取
--4.1 left()
print left('大野太菜了!!!',5)--大野太菜了
--4.2 right()
print right('大野太菜了!!!',3)--!!!
--4.3 substring()截取字串
print substring('大野太菜了!!!',3,3)--太菜了
print substring('大野太菜了!!!',-2,5)--
------------------------------------------日期函式------------------------------------------
print getdate()
print sysdatetime()
print dateadd()--增加時間
select dateadd(day,200,getdate())
select dateadd(month,200,getdate())
select dateadd(year,200,getdate())
select dateadd(minute,200,getdate())
select dateadd(second,200,getdate())
select dateadd(hour,200,getdate())
--查詢入學大于一年的學生,用DATEADD()
select * from studenttest
where DATEADD(DAY,365,jointime)<=GETDATE()
--計算兩個時間的差
select DATEDIFF(YEAR,'1991-5-31',GETDATE())
--查詢出入職N年的人的個數
select 入職時間=DATEDIFF(YEAR,jointime,GETDATE()),人數=COUNT(*) from studenttest group by DATEDIFF(YEAR,jointime,GETDATE())
--獲取日期的某部分的值@return int
print datepart(year,getdate())
print year(getdate())
print datepart(month,getdate())
print month(getdate())
print datepart(day,getdate())
print day(getdate())
--回傳日志的某部分值@return string
print datename(year,getdate())
--查詢出,不同年份入職的員工的個數
select
入學日期=YEAR(jointime),
COUNT(*)
from studenttest
group by jointime
-------------------------------題目
create table tonghua(
id int identity(1,1) primary key,
CellNumber varchar(20),
TelNum varchar(20),
StartDateTime datetime,
EndDateTime datetime
)
drop table tonghua
select * from tonghua
insert into tonghua
select '001','02088888','2010-07-10 10:00:00','2010-07-10 10:05:03' union all
select '001','02088888','2010-07-11 13:00:00','2010-07-11 13:01:10' union all
select '001','89898989','2010-07-11 14:06:00','2010-07-11 14:09:00' union all
select '002','98987676','2010-07-13 21:06:00','2010-07-13 21:08:08' union all
select '002','02188839389','2010-06-29 20:11:00','2010-06-29 20:16:06' union all
select '001','767676766','2010-07-15 13:16:00','2010-07-15 13:26:00' union all
select '003','0227864656','2010-07-13 11:16:00','2010-07-13 11:17:09' union all
select '003','676765777','2010-07-19 19:26:02','2010-07-19 19:30:33' union all
select '001','89977653','2010-06-19 15:16:02','2010-06-19 15:26:10' union all
select '004','400400400','2010-06-19 23:40:02','2010-06-20 10:10:00'
--輸出所有資料中通話時間最長的5條記錄,
select top 5 *,通話時長=datediff(second,startdatetime,enddatetime)
from tonghua
order by 通話時長 desc
--輸出所有資料中撥打長途號碼(對方號碼以0開頭)的總時長.
select * ,通話時間=DATEDIFF(SECOND,startdatetime,enddatetime)
from tonghua
where telnum like '0%'
--假設今天是'2010-07-31'
--輸出本月通話時間總時長最多的前三個呼叫員的編號
select top 3
cellnumber,
通話時長=sum(datediff(second,startdatetime,enddatetime))
from tonghua
where DATEDIFF(MONTH,startdatetime,'2010-07-31 00:00:00')=0--表示是本月
group by cellnumber
order by 通話時長 desc
--輸出本月撥打電話次數最多的前三額呼叫元的編號
select
top 3
cellnumber,
撥打電話次數=COUNT (*)
from tonghua
where DATEDIFF(MONTH,startdatetime,'2010-07-31 00:00:00')=0
group by cellnumber
order by 撥打電話次數 desc
----------------------------------------------第一階段結束-------------------------------------------------------
------------------------------------------------內連接--------------------------------------------------------
create table PhoneType
(
ptId int identity(1,1) primary key,
ptName nvarchar(20)
)
create table PhoneNum
(
pId int identity(1,1) primary key,
pTypeId int,
pName nvarchar(20),
pCellPhone varchar(20),
pHomePhone varchar(20)
)
drop table PhoneType
drop table PhoneNum
insert into PhoneNum
select '1','劉備','13000000000','7000000' union all
select '1','關羽','13000000001','7000001' union all
select '1','張飛','13000000002','7000002' union all
select '2','曹操','13000000003','7000003' union all
select '2','大喬','13000000004','7000004' union all
select '3','孫權','13000000003','7000003' union all
select '3','小喬','13000000004','7000004'
insert into PhoneType
select '朋友' union all
select '同事' union all
select '同學' union all
select '家人'
select * from PhoneType
select * from PhoneNum
select * from PhoneType,PhoneNum --笛卡爾積
select *
from PhoneNum inner join PhoneType on PhoneNum.pTypeId=PhoneType.ptId --7條
select *
from PhoneNum inner join PhoneType on PhoneNum.pTypeId<>PhoneType.ptId --21條
--查詢的時候,如果表中有重名的列,此時,應該在通過 表名.列名 的方式來限定指定哪張表中的
select
pn.pid,
pn.pname,
pn.pcellphone,
pt.ptname
FROM PhoneNum as pn inner join PhoneType as pt on pn.pTypeId=pt.ptId
------------------------------------------------CASE多分支陳述句--------------------------------------------------------
create table [user](
[uid] int identity(1,1) primary key,
name nvarchar(20),
[level] int,
)
insert into [user]
select '犀利哥','1' union
select '小月月','2' union
select '芙蓉姐姐','3'
select * from [user]
------相當于if-else
select
*,
頭銜=case
when [level]=1 then '菜鳥'
when [level]=2 then '老鳥'
when [level]=3 then '大師'
else '骨灰級大師'
end
from [user]
------相當于switch
select
*,
頭銜=case [level]
when 1 then '菜鳥'
when 2 then '老鳥'
when 3 then '大師'
else '骨灰級大師'
end
from [user]
select * from studenttest
select
*,
等級=case
when cj>90 then '優秀'
when cj>80 then '良好'
when cj>70 then '中等'
when cj>59 then '及格'
when cj>0 then '不及格'
else '沒有參加考試'
end
from studenttest
--當A列大于B列時候選擇A,當B列大于C列的時候選擇c
create table ABC(
a int,
b int,
c int
)
insert into ABC
select '10','20','30' union
select '20','30','10' union
select '30','20','20' union
select '10','20','30'
select * from ABC
select 新A=case
when a>b then a
else b
end,
新B=case
when b>c then b
else c
end
from abc
-------------------
create table qiudui
(
scoreId int identity(1,1) primary key,
teamName nvarchar(20),
gameDate datetime,
gameResult nvarchar(20)
)
insert into qiudui
select '公牛','2012-05-01','勝' union
select '小牛','2012-06-01','勝' union
select '奇才','2012-05-15','負' union
select '湖人','2012-07-10','勝' union
select '公牛','2012-06-02','勝' union
select '公牛','2012-07-09','勝' union
select '奇才','2012-03-12','負' union
select '公牛','2012-09-11','負'
select * from qiudui
-----第一步
select
球隊名稱=teamname,
勝=case
when gameResult='勝' then 1
else 0
end,
負=case
when gameResult='負' then 1
else 0
end
from qiudui
-------第二步,第一步和第二步一起執行看看就懂了
select
球隊名稱=teamname,
勝=sum(case
when gameResult='勝' then 1
else 0
end),
負=sum(case
when gameResult='負' then 1
else 0
end)
from qiudui
group by teamname
-------上面題目使用count實作
select
球隊名稱=teamname,
勝=count(case
when gameResult='勝' then '勝'
else null
end),
負=count(case
when gameResult='負' then '負'
else null
end)
from qiudui
group by teamname
-------------------
create table StudentScroe(
aotuid int identity(1,1),
studentid int,
coursename nvarchar(20),
score int
)
drop table StudentScroe
insert into StudentScroe
select '001','語文','90' union all
select '001','數學','99' union all
select '001','英語','95' union all
select '002','語文','80' union all
select '002','數學','89' union all
select '002','英語','91' union all
select '003','語文','86' union all
select '003','數學','92' union all
select '003','英語','77'
-----第一步
select * from StudentScroe
select studentid,
語文=case
when coursename='語文' then score
else null
end,
數學=case
when coursename='數學' then score
else null
end,
英語=case
when coursename='英語' then score
else null
end
from StudentScroe
-----第二步
select studentid,
語文=max(case
when coursename='語文' then score
else null
end),
數學=max(case
when coursename='數學' then score
else null
end),
英語=max(case
when coursename='英語' then score
else null
end)
from StudentScroe
group by studentid
-------------------------------------------索引---------------------------------------------
--1.索引的目的,提高查詢效率
--2.索引分兩種
--2.1聚集索引(物理),一個表中只能有一個聚集索引
--2.2非聚集索引(邏輯),一個表中可以有多個聚集索引
--3.增加索引后,會增加額外的存盤空間,同時降低了增加新紀錄,修改,洗掉的效率
--創建非聚集索引
create nonclustered index 索引名稱 on [column]--列
--創建唯一非聚集索引
create unique nonclustered 索引名稱 index [column]--列
--創建聚集索引
create clustered index 索引名稱 on [column]--列
--洗掉索引
drop index [column]--列
-------------------------------------------子查詢---------------------------------------------
/*子查詢:把一個查詢的結果在另外一個查詢中使用叫子查詢
子查詢的基本分類
1.獨立子查詢:
子查詢可以獨立運行
2.相關子查詢
子查詢中參考了父查詢中的結果

*/
---------------------------------------分頁查詢---------------------------------------
---------------------------------------使用TOP分頁
--要分頁查詢,或者分頁顯示,首先要確定按照上面排序,然后才能確定哪些記錄該在第一頁,哪些記錄該在應該在第二頁
--第一頁顯示7條資料
--第1頁
select top 7 * from studenttest order by xh asc
--查詢前兩頁的資料
select top (7*2) * from studenttest order by xh asc
--第2頁
--2.1先查詢出(2-1)頁的資料的xh
select top 7 * from studenttest where xh not in
(select top 7 xh from studenttest order by xh asc)
order by xh
---------------------------------------使用row_number()實作分頁
--1.為資料排序人,然后編號,
select *,Rn=row_number() over(order by xh asc) from studenttest
--2.根據用戶要查看的每頁記錄條數,以及要查看第幾頁,確定應該查詢第幾條到第幾條
--每頁顯示7條,要查看第4頁
--從3*7+1.....4*7
select *
from(select *,Rn=row_number() over(order by xh asc) from studenttest) as t
where t.Rn between 3*7+1 and 4*7
---------------------------------------連接查詢---------------------------------------
--內連接:值顯示那些兩張表中可以匹配的資料
--左外連接:坐標為主,左表的資料全部顯示,左右表匹配的資料顯示在右表,不匹配的資料顯示NULL
-----------------------------------事務,索引,視圖,同義詞
/*
1.事務的概念
事務時一種機制,它包含了一組資料庫操作命令,而且將所有的命名作為一個整體一起向資料庫提交或撤銷,這組命令要么都執行,要么都不執行,所以事務時一個不可分割的邏輯作業單元
2.事務的特點
雖然事務的每個執行單元都不相同,但所有的事物都具有4個特征,原子性,一致性,隔離性,持久性,簡稱ACID
3.事務的隔離級別
事務的4個特征中,隔離性用來解決多用戶操作中的并發沖突問題,
隔離級別:
未提交讀(read uncommitted)
已提交讀(read committed)
重復讀 (repeatable read)
可串行化(serializable)

未提交讀:事務之間最低的隔離級別,改級別只能保證不會讀取損壞的資料,即事務之間沒有什么隔離,事務能夠讀取其他食物正在修改并未提交的資料,這種隔離的級別無法確保資料的正確性

已提交讀:SQL SERVER 默認的隔離級別,改隔離級別能保證其他事務不能讀取當前事務正在修改但未提交的記錄,

重復讀: 這中隔離級別比較高,能確保其他事務不能修改當前事務中正在讀取但未提交的資料

可串行化:最高的隔離級別,事務之間完全隔離,事務之間按串行的方式執行,所以在這種級別的隔離下不存在并行化的操作,要訪問其他事務操作的資料,一定要等其他食物完全完成提交以后才能進行


*/
----------------------------------視圖
--視圖是虛擬表,只能存查詢陳述句,
--特點:安全,簡化操作
--create view viewname as <select 陳述句>
--視圖的查詢陳述句不要order by排序
------------------------------開始事務
begin transaction
declare @sum int=0
--在轉賬之前最好通過if-else判斷,不要讓程式發生例外報錯
update bank set balance=balance-1 where name='你好'
set @sum=@sum+@@error
update bank set balance=balance+1 where name='胡偉'
set @sum=@sum+@@error
--只要有一條sql執行出錯,那么最后的@sum就不是0
if @sum<>0
begin
--表示出錯了
--回滾
rollback
end
else
begin
--如果沒有出錯,則提交該事務
commit
end
--自動提交事務
--當執行一條sql陳述句的時候,資料庫自動幫我們打開一個事務,當陳述句執行成功,資料庫自動提交事務,執行失敗,資料庫自動回滾事務
--隱式事務
--每次執行一條sql陳述句的時候,資料庫自動幫我們打開一個事務,但是需要我們手動提交事務,或者回滾事務
set IMPLICIT_TRANSACTIONS on
set IMPLICIT_TRANSACTIONS off
INSERT INTO BANK VALUES ('有錢人','888888')
SELECT * FROM bank
commit
--顯示事務:需要手動打開事務,手動提交事務或者回滾事務
begin tran
commit tran
rollback tran
-------------------存盤程序
create proc usp_helloworld
as
begin
print 'hello world'
end
exec usp_helloworld
create proc usp_selectEmployee
as
begin
select * from Employee
end
exec usp_selectEmployee
--修改存盤程序
alter proc usp_selectEmployee
as
begin
select * from Employee where DeptNo='d01'
end
exec usp_selectEmployee
--創建一個帶兩個引數的存盤程序
create proc usp_add_number
@n1 int,
@n2 int
as
begin
select @n1+@n2
end
exec usp_add_number 100,500
--
use DB_Teacher
create proc usp_DB_Teacher
@gender char(2),
@studentaddress char(20)
as
begin
select * from student where studentsex=@gender and studentaddress=@studentaddress
end
exec usp_DB_Teacher '男','湖北襄樊'
--設定存盤程序的引數的默認值
--設定引數的默認值以后,呼叫存盤程序的時候要明確實參賦值的形參物件
create proc usp_add_number1
@n1 int,
@n2 int=50
as
begin
select @n1+@n2
end
exec usp_add_number1 100
create proc usp_add_number2
@n1 int=80,
@n2 int
as
begin
select @n1+@n2
end
exec usp_add_number2 @n2=100
---------------------------------------帶輸出引數的存盤程序
--當在存盤程序當中需要回傳多個值的時候,就可以使用輸出引數來回傳這些值,
use DB_Teacher
go
create proc usp_show_student
@gender char(2),
@count int output --輸出引數
as
begin
select * from student where studentsex=@gender
--把查詢陳述句查詢到的記錄條數賦值給變數@count
set @count=(select COUNT(*) from student where studentsex=@gender)
end
--呼叫存盤程序
--呼叫帶有輸出引數的存盤程序的時候,需要定義變數,將變數傳遞給輸出引數,
-- 在存盤程序中使用的輸出引數,其實就是你傳遞進來的變數,
declare @count int
exec usp_show_student @gender='男',@count=@count output
print @count
-------------使用存盤程序撰寫分頁查詢-------------
use PPTDemo
go
select * from studenttest
go
alter procedure usp_fenye
@pagesize int=7, --每頁記錄條數
@pageindex int=1, --當前要查看第幾頁記錄
@recordcount int output, --總的記錄條數
@pagecount int output --總的頁數
as
begin
--1,撰寫查詢陳述句,要把用戶的資料查詢出來
select
t.xh,
t.xm,
t.xb,
t.km,
t.jointime

from(select *,rn=ROW_NUMBER() over(order by xh asc) from studenttest ) as t
where t.rn between (@pageindex-1)*@pagesize+1 and @pageindex*@pagesize

--2,計算總的記錄條數
set @recordcount=(select COUNT(*) from studenttest)

--3,計算總的頁數
set @pagecount=ceiling(@recordcount*1.0/@pagesize)
end
--執行存盤程序
declare @i int,@j int
exec usp_fenye @recordcount=@i output,@pagecount=@j output
print '所有資料'+convert(varchar(10),@i)
print '頁數'+convert(varchar(10),@j)
------------------------------ 通過set賦值,與select賦值的區別
use PPTDemo
go
declare @a int
--set @a=(select COUNT(*) from studenttest) --set賦值
select @a=COUNT(*) from studenttest --select賦值
print @a
set @a=1
select @a=1
--當通過set為變數賦值的時候,如果查詢陳述句回傳的不止一個值的時候直接報錯
--但是,當通過select變數賦值的時候,如果查詢陳述句回傳的不止一個值的時候,那么會將最后一個結果賦值給該變數
------------------------------------觸發器
use Company_DB
create table HongFengHai(
studentid int,
studentname nvarchar(20),
studentgender nvarchar(2),
studentclass nvarchar(20)
)
select * from HongFengHai
select top 0 * into 測驗觸發器 from HongFengHai
go
--創建一個觸發器
create trigger trigger_delete_HongFengHai
on HongFengHai
after delete
as
begin
insert into 測驗觸發器 select * from deleted
end
delete from HongFengHai where studentclass='c語言'

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/28282.html

標籤:SQL Server

上一篇:SQL Server 中 `JSON_MODIFY` 的使用

下一篇:mssql sqlserver 添加表注釋和添加列注釋的方法分享

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more