------------恢復內容開始------------java
-
-----------------------------------------------------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
---------------------------------------------------------------------------第二階段
一、數據庫設計階段
需求分析:收集信息
概念設計:標識實體、標識屬性、標識關係-》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','tom@yahoo.com','','','1000',@stateid,@roleid,'d:\prt\images\tom.jpg' union all
select 'jack123','admin123','jack','1','321032198612126746','jack@yahoo.com','','','1000',@stateid,@roleid,'d:\prt\images\jack.jpg' union all
select 'Slider123','as123','Slider','1','321032198208213232','Slider@yahoo.com','','','1000',@stateid,@roleid,'d:\prt\images\Slider.jpg' union all
select 'Micky123','888888','Micky','1','321032198910102322','Micky@yahoo.com','','','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','84000508@qq.com','','','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','84000508@qq.com','','',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
--------------------------------------------------------------------------------函數和存儲過程
/*
一、函數
定義:一種封裝一條或多條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
-
-----------------------------------------------------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
---------------------------------------------------------------------------第二階段
一、數據庫設計階段
需求分析:收集信息
概念設計:標識實體、標識屬性、標識關係-》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','tom@yahoo.com','','','1000',@stateid,@roleid,'d:\prt\images\tom.jpg' union all
select 'jack123','admin123','jack','1','321032198612126746','jack@yahoo.com','','','1000',@stateid,@roleid,'d:\prt\images\jack.jpg' union all
select 'Slider123','as123','Slider','1','321032198208213232','Slider@yahoo.com','','','1000',@stateid,@roleid,'d:\prt\images\Slider.jpg' union all
select 'Micky123','888888','Micky','1','321032198910102322','Micky@yahoo.com','','','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','84000508@qq.com','','','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','84000508@qq.com','','',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
--------------------------------------------------------------------------------函數和存儲過程
/*
一、函數
定義:一種封裝一條或多條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語言'
shell