一、SQL 基礎知識
1、DDL(數(shù)據(jù)定義語言)
1)創(chuàng)建數(shù)據(jù)表
--創(chuàng)建數(shù)據(jù)表
create table Test(Id int not null, Age char(20));
--創(chuàng)建數(shù)據(jù)表
create table T_Person1(Id int not null,
Name nvarchar(50),
Age int null);
--創(chuàng)建表,添加外鍵
Create table T_Students(
StudentNo char(4),
CourseNo char(4),
Score int,
Primary key(StudentNo),
Foreign key(CourseNo) References T_Course(CourseNo)
);
2)修改表結構
--修改表結構,添加字段
Alter table T_Person add NickName nvarchar(50) null;
--修改表結構,刪除字段
Alter table T_Person Drop NickName;
3)刪除數(shù)據(jù)表
--刪除數(shù)據(jù)表
Drop table T_Person;
--刪除數(shù)據(jù)表
drop table test
4)創(chuàng)建索引
Create [Unique] Index <索引名> on <基本表名>(<列明序列>);
2、DML(數(shù)據(jù)操縱語言)
1)插入語句
insert into T_Person1(Id,Name,Age) values(1,'Vicky',20)
--插入一條據(jù)數(shù),字段和值必須前后對應
insert into T_Preson1(Id,Name,Age) values(2,'Tom',19)
insert into T_Person1(Id,Name,Age) values(4,'Jim',19)
insert into T_Person1(Id,Name,Age) values(5,'Green',20)
insert into T_Person1(Id,Name,Age) values(6,'Hanmeimei',21)
insert into T_Person1(Id,Name,Age) values(7,'Lilei',22)
insert into T_Person1(Id,Name,Age) values(8,'Sky',23)
insert into T_Person1(Id,Name,Age) values(newid(),'Tom',19)
2)更新語句
--修改列,把所有的age字段改為30
update T_Person1 set age=30
--把所有的Age字段和Name字段設置為...
update T_Person1 set Age=50,Name='Lucy'
update T_Person1 set Name='Frankie' where Age=30
update T_Person1 set Name=N'中文字符' where Age=20
--中文字符前面最好加上N,以防出現(xiàn)亂碼
update T_Person1 set Name=N'成年人' where Age=30 or Age=50
3)刪除語句
delete from T_Person1
--刪除表中全部數(shù)據(jù)
delete from T_Person1 where Name='Tom'
--根據(jù)條件刪除數(shù)據(jù)
4)查詢語句
查詢語句非常強大,幾乎可以查任意東西!
-----------------
---- 數(shù)據(jù)檢索 -----
-----------------
--查詢不與任何表關聯(lián)的數(shù)據(jù).
SELECT 1+1; --簡單運算
select 1+2 as 結果
SELECT newid();--查詢一個GUID字符創(chuàng)
select GETDATE() as 日期 --查詢日期
--可以查詢SQLServer版本
select @@VERSION as SQLServer版本
--一次查詢多個
select 1+1 結果, GETDATE() as 日期, @@VERSION as 版本, NEWID() as 編號
--簡單的數(shù)據(jù)查詢.HelloWorld級別
SELECT * FROM T_Employee;
--只查詢需要的列.
SELECT FNumber FROM T_Employee;
--給列取別名.As關鍵字
SELECT FNumber AS 編號, FName AS 姓名 FROM T_Employee;
--使用 WHERE 查詢符合條件的記錄.
SELECT FName FROM T_Employee WHERE FSalary<5000;
--對表記錄進行排序,默認排序規(guī)則是ASC
SELECT * FROM T_Employee ORDER BY FAge ASC,FSalary DESC;
--ORDER BY 子句要放在 WHERE 子句之后.
SELECT * FROM T_Employee WHERE FAge>23 ORDER BY FAge DESC,FSalary DESC;
--WHERE 中可以使用的邏輯運算符:or、and、not、<、>、=、>=、<=、!=、<>等.
--模糊匹配,首字母未知.
SELECT * FROM T_Employee WHERE FName LIKE '_arry';
--模糊匹配,前后多個字符未知.
SELECT * FROM T_Employee WHERE FName LIKE '%n%';
--NULL 表示"不知道",有 NULL 參與的運算結果一般都為 NULL.
--查詢數(shù)據(jù)是否為 NULL,不能用 = 、!= 或 <>,要用IS關鍵字
SELECT * FROM T_Employee WHERE FName IS NULL;
SELECT * FROM T_Employee WHERE FName IS NOT NULL;
--查詢在某個范圍內的數(shù)據(jù),IN 表示包含于,IN后面是一個集合
SELECT * FROM T_Employee WHERE FAge IN (23, 25, 28);
--下面兩條查詢語句等價。
SELECT * FROM T_Employee WHERE FAge>=23 AND FAge<=30;
SELECT * FROM T_Employee WHERE FAge BETWEEN 23 AND 30;
----創(chuàng)建一張Employee表,以下幾個Demo中會用的這張表中的數(shù)據(jù)
----在SQL管理器中執(zhí)行下面的SQL語句,在T_Employee表中進行練習
create table T_Employee(FNumber varchar(20),
FName varchar(20),
FAge int,
FSalary Numeric(10,2),
primary key (FNumber)
)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('DEV001','Tom',25,8300)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('DEV002','Jerry',28,2300.83)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('SALES001','Lucy',25,5000)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('SALES002','Lily',25,6200)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('SALES003','Vicky',25,1200)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('HR001','James',23,2200.88)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('HR002','Tom',25,5100.36)
insert into T_Employee(FNumber,FName,FAge,FSalary) values('IT001','Tom',28,3900)
insert into T_Employee(FNumber,FAge,FSalary) values('IT002',25,3800)
--開始對T_Employee表進行各種操作
--檢索所有字段
select * from T_Employee
--只檢索特定字段
select FName,FAge from T_Employee
--帶過濾條件的檢索
select * from T_Employee
where FSalary<5000
--可更改顯示列名的關鍵字as,as—起別名
select FName as 姓名,FAge as 年齡,FSalary as 薪水 from T_Employee
二、SQL Server 中的數(shù)據(jù)類型
1、精確數(shù)字類型
bigint
int
smallint
tinyint
bit
money
smallmoney
2、字符型數(shù)據(jù)類型,MS建議用VarChar(max)代替Text
Char
VarChar
Text
3、近似數(shù)字類型
Decimal
Numeric
Real
Float
4、Unicode字符串類型
Nchar
NvarChar
Ntext
5、二進制數(shù)據(jù)類型,MS建議VarBinary(Max)代替Image數(shù)據(jù)類型,max=231-1
Binary(n) 存儲固定長度的二進制數(shù)據(jù)
VarBinary(n) 存儲可變長度的二進制數(shù)據(jù),范圍在n~(1,8000)
Image 存儲圖像信息
6、日期和時間類型,數(shù)據(jù)范圍不同,精確地不同
DateTime
SmallDateTime
7、特殊用途數(shù)據(jù)類型
Cursor
Sql-variant
Table
TimeStamp
UniqueIdentifier
XML
三、SQL中的內置函數(shù)
--------------------------------------
----- 數(shù)據(jù)匯總-聚合函數(shù) ---------
--------------------------------------
--查詢T_Employee表中數(shù)據(jù)條數(shù)
select COUNT(*) from T_Employee
--查詢工資最高的人
select MAX(FSalary) as Top1 from T_Employee
--查詢工資最低的人
select Min(FSalary) as Bottom1 from T_Employee
--查詢工資的平均水平
select Avg(FSalary) as 平均水平 from T_Employee
--所有工資的和
select SUM(FSalary) as 總工資 from T_Employee
--查詢工資大于5K的員工總數(shù)
select COUNT(*) as total from T_Employee
where FSalary>5000
------------------------------
----- 數(shù)據(jù)排序 -------
------------------------------
--按年齡排序升序,默認是升序
select * from T_Employee
order by FAge ASC
--多個條件排序,先什么,后什么,在前一個條件相同的情況下,根據(jù)后一個條件進行排列
--where在order by之前
select * from T_Employee
order by FAge ASC, FSalary DESC
------------------------------
----- 模糊匹配 -------
------------------------------
--通配符查詢
--1.單字符通配符_
--2.多字符通配符%
--以DEV開頭的任意個字符串
select * from T_Employee
where FNumber like 'DEV%'
--以一個字符開頭,om結尾的字符串
select * from T_Employee
where FName like '_om'
--檢索姓名中包含m的字符
select * from T_Employee
where FName like '%m%'
------------------------------
----- 空值處理 -------
------------------------------
--null表示不知道,不是沒有值
--null和其他值計算結果是null
select null+1
--查詢名字是null的數(shù)據(jù)
select * from T_Employee
where FName is null
--查詢名字不為空null的數(shù)據(jù)
select * from T_Employee
where FName is not null
--年齡是23,25,28中的員工
select * from T_Employee
where FAge=23 or FAge=25 or FAge=28
--或者用in 集合查詢
--年齡是23,25,28中的員工
select * from T_Employee
where FAge in (23,25,28)
--年齡在20到25之間的員工信息
select * from T_Employee
where FAge>20 and FAge<25
--年齡在20到25之間的員工信息,包含25
select * from T_Employee
where FAge between 20 and 25
------------------------------
----- 數(shù)據(jù)分組 -------
------------------------------
Select FAge,COUNT(*) from T_Employee
group by FAge
--1.根據(jù)年齡進行分組
--2.再取出分組后的年齡的個數(shù)
--注意:沒有出現(xiàn)在group by 子句中的字段,不能出現(xiàn)在select語句后的列名列表中(聚合函數(shù)除外)
--group by 必須出現(xiàn)在where后面
Select FAge,AVG(FSalary),COUNT(*) from T_Employee
group by FAge
--錯誤用法
Select FAge,FName,COUNT(*) from T_Employee
group by FAge
--加上where的group by 子句
--group by 必須出現(xiàn)在where后面
Select FAge,AVG(FSalary),COUNT(*) from T_Employee
where FAge>=25
group by FAge
--Having不能包含查不到的字段,只能包含聚合函數(shù)和本次查詢有關的字段
select FAge,COUNT(*) from T_Employee
group by FAge
Having COUNT(*)>1
select FAge,COUNT(*) from T_Employee
where FSalary>2500
group by FAge
--HAVING 子句中的列 'T_Employee.FSalary' 無效,因為該列沒有包含在聚合函數(shù)或 GROUP BY 子句中
--Having是對分組后信息的過濾,能用的列和select中能有的列是一樣的。
--因此,having不能代替where
select FAge,COUNT(*) from T_Employee
group by FAge
Having FSalary>2500
------------------------------
----- 確定結果集行數(shù) -------
------------------------------
--取出所有員工的信息,根據(jù)工資降序排列
select * from T_Employee
order by FSalary DESC
--取出前三名員工的信息,根據(jù)工資降序排列
select top 3 * from T_Employee
order by FSalary DESC
--根據(jù)工資取出排名在6-8的員工信息,按工資降排列
select top 3 * from T_Employee
where FNumber not in
(select top 5 FNumber from T_Employee order by FSalary DESC)
order by FSalary DESC
---修改數(shù)據(jù)表,添加字段,更新字段的值等操作。
alter table T_Employee add FSubCompany varchar(20)
alter table T_Employee add FDepartment varchar(20)
update T_Employee set FSubCompany='Beijing',FDepartment='Development'
where FNumber='DEV001';
update T_Employee set FSubCompany='ShenZhen',FDepartment='Development'
where FNumber='DEV002';
update T_Employee set FSubCompany='Beijing',FDepartment='HumanResource'
where FNumber='HR001';
update T_Employee set FSubCompany='Beijing',FDepartment='HumanResource'
where FNumber='HR002';
update T_Employee set FSubCompany='Beijing',FDepartment='InfoTech'
where FNumber='IT001';
update T_Employee set FSubCompany='ShenZhen',FDepartment='InfoTech'
where FNumber='IT002'
update T_Employee set FSubCompany='Beijing',FDepartment='Sales'
where FNumber='SALES001';
update T_Employee set FSubCompany='Beijing',FDepartment='Sales'
where FNumber='SALES002';
update T_Employee set FSubCompany='ShenZhen',FDepartment='Sales'
where FNumber='SALES003';
select * from T_Employee
------------------------------
------ 去掉重復數(shù)據(jù) ------
------------------------------
--所有員工的部門信息
select Distinct FDepartment from T_Employee;
select FDepartment,FSubCompany
from T_Employee
--以上兩個例子結合起來比較,Distinct針對的是整行進行比較的
select Distinct FDepartment,FSubCompany
from T_Employee
------------------------------
----- 聯(lián)合結果集Union --------
------------------------------
--創(chuàng)建一個測試表T_TempEmployee,并插入數(shù)據(jù)
Create Table T_TempEmployee(FIdCardNumber varchar(20),FName varchar(20),FAge int,Primary key(FIdCardNumber));
insert into T_TempEmployee(FIdCardNumber,FName,FAge) values('1234567890121','Sarani',33);
insert into T_TempEmployee(FIdCardNumber,FName,FAge) values('1234567890122','Tom',26);
insert into T_TempEmployee(FIdCardNumber,FName,FAge) values('1234567890123','Yamaha',38);
insert into T_TempEmployee(FIdCardNumber,FName,FAge) values('1234567890124','Tina',36);
insert into T_TempEmployee(FIdCardNumber,FName,FAge) values('1234567890125','Konkaya',29);
insert into T_TempEmployee(FIdCardNumber,FName,FAge) values('1234567890126','Foortia',29);
select * from T_TempEmployee
--Union關鍵字,聯(lián)合2個結果
--把2個查詢結果結合為1個查詢結果
--要求:上下2個查詢語句的字段(個數(shù),名字,類型相容)必須一致
select FName,Fage from T_TempEmployee
union
select FName,Fage from T_Employee
select FNumber, FName,Fage,FDepartment from T_Employee
union
select FIdCardNumber,FName,Fage,'臨時工,無部門' from T_TempEmployee
---Union All:不合并重復數(shù)據(jù)
--Union:合并重復數(shù)據(jù)
select FName,FAge from T_Employee
union all
select FName,FAge from T_TempEmployee
select FAge from T_Employee
union
select FAge from T_TempEmployee
--注意:Union因為要進行重復值掃描,所以效率低,因此如果不是確定要合并重復,那么就用Union all
--例子:報名
select '正式員工最高年齡',MAX(FAge) from T_Employee
union all
select '正式員工最低年齡',MIN(FAge) from T_Employee
union all
select '臨時工最高年齡',MAX(FAge) from T_TempEmployee
union all
select '臨時工最低年齡',MIN(FAge) from T_TempEmployee
--查詢每位正式員工的信息,包括工號,工資,并且在最后一行加上員工工資額合計
select FNumber,FSalary from T_Employee
union all
select '工資額合計',SUM(FSalary) from T_Employee
------------------------------
----- SQL其他內置函數(shù) ------
------------------------------
--1.數(shù)學函數(shù)
--ABS():求絕對值
--CEILING():舍入到最大整數(shù)
--FLOOR():舍入到最小整數(shù)
--ROUND():四舍五入
select ABS(-3)
select CEILING(3.33)
select CEILING(-3.61)
select FLOOR(2.98)
select FLOOR(-3.61)
select ROUND(-3.61,1)--第二個參數(shù)是精度,小數(shù)點后的位數(shù)
select ROUND(-3.61,0)
select ROUND(3.1415926,3)
--2.字符串函數(shù)
--LEN():計算字符串長度
--LOWER(),UPPER():轉大小寫
--LTRIM():去掉字符串左側的空格
--RTRIM():去掉字符串右側的空格
--SUBSTRING(string,start_positoin,length):
--索引從1開始
select SUBSTRING('abc111',2,3)--結果是bc1
select FName, SUBSTRING(FName,2,2) from T_Employee
select LEN('abc') --結果是3
select FName, LEN(FName) from T_Employee
--沒有可以同時既去掉左邊空格、又去掉右邊空格的TRIM()內置函數(shù),所以先左后右的進行TRim,當然,你也可以先右后左
select LTRIM(' abc '),RTRIM(' abc '),LEN(LTRIM(RTRIM(' abc ')))
--3.日期函數(shù)
--GETDATE():獲取當前日期時間
--DATEADD(datepart,numbre,date):計算增加以后的日期,
--參數(shù)date為待計算的日期;參數(shù)number為增量;參數(shù)datepart為計量單位,時間間隔單位;
--DATEDIFF(datepart,startdate,enddate):計算2個日期之間的差額
--DATEPART(datepart,date):返回一個日期的特定部分,比如年月日,時分秒等.
/*
值 縮 寫(Sql Server) (Access 和 ASP) 說明
Year Yy yyyy 年 1753 ~ 9999
Quarter Qq q 季 1 ~ 4
Month Mm m 月 1 ~ 12
Day of year Dy y 一年的日數(shù),一年中的第幾日 1-366
Day Dd d 日, 1-31
Weekday Dw w 一周的日數(shù),一周中的第幾日 1-7
Week Wk ww 周,一年中的第幾周 0 ~ 51
Hour Hh h 時0 ~ 23
Minute Mi n 分鐘0 ~ 59
Second Ss s 秒 0 ~ 59
Millisecond Ms - 毫秒 0 ~ 999
*/
select DATEADD(DAY,3,getdate())
select DATEADD(MONTH,-3,getdate())
select DATEADD(HOUR,8,getdate())
select DATEDIFF(YEAR,'1989-05-01',GETDATE())
select DATEDIFF(HH,GETDATE(),DATEADD(DAY,-3,GETDATE()))
--查詢員工的工齡,年為單位
select FName,FInDate,DATEDIFF(year,FInDate,getdate()) as 工齡 from T_Employee
--取出每一年入職員工的個數(shù)V1
select DATEDIFF(year,FInDate,getdate()),COUNT(*)
from T_Employee
group by DATEDIFF(year,FInDate,getdate())
--取出每一年入職員工的個數(shù)V2
select DATEPART(YEAR,FInDate), COUNT(*)
from T_Employee
group by DATEPART(YEAR,FInDate)
select DATEPART(YEAR,GETDATE())
select DATEPART(MONTH,GETDATE())
select DATEPART(DAY,GETDATE())
select DATEPART(HH,GETDATE())
select DATEPART(MINUTE,GETDATE())
select DATEPART(SECOND,GETDATE())
--4.類型轉換函數(shù)
--CAST(expression as data_type)
--CONVERT(data_type,expression)
select CAST('123' as int),CAST('2010-09-08' as datetime),
CONVERT(datetime,'2010-09-08'),CONVERT(varchar(20),123)
--5.空值處理函數(shù)isNull
--ISNULL(expression,value)
select ISNULL(FName,'佚名') as 姓名 from T_Employee
--6.CASE函數(shù)用法:
--1.單值判斷:相當于switch.case
--CASE expression
--WHEN value1 then returnvalue1
--WHEN value2 then returnvalue2
--WHEN value3 then returnvalue3
--ELSE default_return_value
--END
--判斷客戶類型
select FName,
(
case FLevel
when 1 then '普通客戶'
when 2 then '會員'
when 3 then 'VIP'
else '未知客戶類型'
End
) as 客戶類型
from T_Customer
--收入水平查詢
select FName,
(
case
when FSalary < 2000 then '低收入'
when FSalary >= 2000 and FSalary <=5000 then '中等收入'
else '高收入'
end
)as 收入水平
from T_Employee
--這里有一道關于CASE用法的面試題
--表T中有ABC三列,用SQL語句實現(xiàn):當A列大于B列時選擇A列,否則選擇B列;
--當B列大于C列時選擇B列,否則選擇C列。
select
(
case
when a > b then a else b
end
),
(
case
when b>c then b else c
end
)
from T
---------------------------------------
select FNumber,
(
case
when FAmount>0 then FAmount
else 0
end
) as 收入,
(
case
when FAmount<0 then ABS(FAmount)
else 0
end
) as 支出
from T
-----------------------------------------
--球隊比賽那個題
--有一張表T_Scroes,記錄比賽成績:
--Date Name Scroe
--2008-8-8 拜仁 勝
--2008-8-9 奇才 勝
--2008-8-8 湖人 勝
--2008-8-10 拜仁 負
--2008-8-8 拜仁 負
--2008-8-12 奇才 勝
--要求輸出下面格式:
--Name 勝 負
--拜仁 1 2
--湖人 1 0
--奇才 2 0
--注意:在中文字符串前加 N,比如 N'勝'
create table T_Scores(
[Date] datetime null collate
[Name] nvarchar(50)
)
CREATE TABLE [T_Scores]( [Date] [datetime] NULL,
[Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Score] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL
);
INSERT [T_Scores] ([Date], [Name], [Score]) VALUES (CAST(0x00009AF200000000 AS DateTime), N'拜仁', N'勝');
INSERT [T_Scores] ([Date], [Name], [Score]) VALUES (CAST(0x00009AF300000000 AS DateTime), N'奇才', N'勝');
INSERT [T_Scores] ([Date], [Name], [Score]) VALUES (CAST(0x00009AF300000000 AS DateTime), N'湖人', N'勝');
INSERT [T_Scores] ([Date], [Name], [Score]) VALUES (CAST(0x00009AF400000000 AS DateTime), N'拜仁', N'負');
INSERT [T_Scores] ([Date], [Name], [Score]) VALUES (CAST(0x00009AF200000000 AS DateTime), N'拜仁', N'負');
INSERT [T_Scores] ([Date], [Name], [Score]) VALUES (CAST(0x00009AF600000000 AS DateTime), N'奇才', N'勝');
select * from T_Scores
--列出第一個表格
--統(tǒng)計每支隊伍的勝負情況
select Name,
(
case Score
when N'勝' then 1
else 0
end
) as 勝,
(
case Score
when N'負' then 1
else 0
end
) as 負
from T_Scores
select Name,
sum
(
case Score
when N'勝' then 1
else 0
end
) as 勝,
sum
(
case Score
when N'負' then 1
else 0
end
) as 負
from T_Scores
group by Name
--根據(jù)每個隊的勝負判斷出勝負的場數(shù)
--題5) 創(chuàng)建一張表,記錄電話呼叫員的工作流水,記錄呼叫員編號,對方號碼,通話開始時間,通話結束時間,。
--創(chuàng)建一張表T_Callers,記錄電話呼叫員的工作流水,記錄呼叫員編號、對方號碼、通話開始時間、通話結束時間。建表、插數(shù)據(jù)等最后都自己寫SQL語句。
--要求:
-- 1) 輸出所有數(shù)據(jù)中通話時間最長的5條記錄。
-- 2) 輸出所有數(shù)據(jù)中撥打長途號碼(對方號碼以0開頭)的總時長。
-- 3) 輸出本月通話總時長最多的前三個呼叫員的編號。
-- 4) 輸出本月?lián)艽螂娫挻螖?shù)最多的前三個呼叫員的編號。
-- 5) 輸出所有數(shù)據(jù)的撥號流水,并且在最后一行添加總呼叫時長。
-- 記錄呼叫員編號、對方號碼、通話時長
-- ......
-- 匯總[市內號碼總時長][長途號碼總時長]
--Id CallerNumber TellNumber StartDateTime EndDateTime
--1 001 02088888888 2010-7-10 10:01 2010-7-10 10:05
--2 001 02088888888 2010-7-11 13:41 2010-7-11 13:52
--3 001 89898989 2010-7-11 14:42 2010-7-11 14:49
--4 002 02188368981 2010-7-13 21:04 2010-7-13 21:18
--5 002 76767676 2010-6-29 20:15 2010-6-29 20:30
--6 001 02288878243 2010-7-15 13:40 2010-7-15 13:56
--7 003 67254686 2010-7-13 11:06 2010-7-13 11:19
--8 003 86231445 2010-6-19 19:19 2010-6-19 19:25
--9 001 87422368 2010-6-19 19:25 2010-6-19 19:36
--10 004 40045862245 2010-6-19 19:50 2010-6-19 19:59
-- 創(chuàng)建表
create table T_CallRecords(
id int not null,
CallerNumber varchar(3),
TellNumber varchar(13),
StartDateTIme datetime,
EndDateTime datetime,
Primary key(Id)
);
--插入數(shù)據(jù)
insert into T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTIme)
values(1,'001','02088888888','2010-7-10 10:01','2010-7-10 10:05');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (2,'002','02088888888', '2010-7-11 13:41','2010-7-11 13:52');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (3,'003','89898989', '2010-7-11 14:42', '2010-7-11 14:49');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (4,'004','02188368981', '2010-7-13 21:04', '2010-7-13 21:18');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (5,'005','76767676', '2010-6-29 20:15', '2010-6-29 20:30');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (6,'006','02288878243', '2010-7-15 13:40', '2010-7-15 13:56');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (7,'007','67254686', '2010-7-13 11:06', '2010-7-13 11:19');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (8,'008','86231445', '2010-6-19 19:19', '2010-6-19 19:25');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (9,'009','87422368', '2010-6-19 19:25', '2010-6-19 19:36');
INSERT INTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)
VALUES (10,'010','40045862245', '2010-6-19 19:50', '2010-6-19 19:59');
--修改呼叫員編號
UPDATE T_CallRecords SET CallerNumber='001' WHERE Id IN (1,2,3,6,9);
UPDATE T_CallRecords SET CallerNumber='002' WHERE Id IN (4,5);
UPDATE T_CallRecords SET CallerNumber='003' WHERE Id IN (7,8);
UPDATE T_CallRecords SET CallerNumber='004' WHERE Id=10;
--數(shù)據(jù)匯總
select * from T_CallRecords
--題 1): 輸出所有數(shù)據(jù)中通話時間最長的5條記錄。
--@計算通話時間;
--@按通話時間降序排列;
--@取前5條記錄。
select top 5 CallerNumber,DATEDIFF(SECOND,StartDateTime,EndDateTime) as 總時長
from T_CallRecords
order by DATEDIFF(SECOND,StartDateTime,EndDateTime) DESC
--題 2):輸出所有數(shù)據(jù)中撥打長途號碼(對方號碼以0開頭)的總時長
--@查詢撥打長途號碼的記錄;
--@計算各撥打長途號碼的通話時長;
--@對各撥打長途號碼的通話時長進行求和。
select SUM(DATEDIFF(SECOND,StartDateTime,EndDateTime)) as 總時長 from T_CallRecords
where TellNumber like '0%'
--題 3):輸出本月通話總時長最多的前三個呼叫員的編號。
--@按呼叫員編號進行分組;
--@計算各呼叫員通話總時長;
--@按通話總時長進行降序排列;
--@查詢前3條記錄中呼叫員的編號。
select datediff(month,convert(datetime,'2010-06-01'),convert(datetime,'2010-07-22'))--測試
select CallerNumber,TellNumber,datediff(month,StartDateTime,EndDateTime)
from T_CallRecords
select top 3 CallerNumber from T_CallRecords
where datediff(month,StartDateTime,getdate())=12--一年前的
group by CallerNumber
order by SUM(DATEDIFF(SECOND,StartDateTime,EndDateTime)) DESC
--題 4) 輸出本月?lián)艽螂娫挻螖?shù)最多的前三個呼叫員的編號.
--@按呼叫員編號進行分組;
--@計算個呼叫員撥打電話的次數(shù);
--@按呼叫員撥打電話的次數(shù)進行降序排序;
--@查詢前3條記錄中呼叫員的編號。
select top 3 CallerNumber,count(*)
from T_CallRecords
where datediff(month,StartDateTime,getdate())=12--一年前的
group by CallerNumber
order by count(*) DESC
--題5) 輸出所有數(shù)據(jù)的撥號流水,并且在最后一行添加總呼叫時長:
-- 記錄呼叫員編號、對方號碼、通話時長
-- ......
-- 匯總[市內號碼總時長][長途號碼總時長]
--@計算每條記錄中通話時長;
--@查詢包含不加 0 號碼,即市內號碼的記錄;
--@計算市內號碼通話總時長;
--@查詢包含加 0 號碼,即長途號碼的記錄;
--@計算長途號碼通話總時長;
--@聯(lián)合查詢。
select '匯總' as 匯總,
convert(varchar(20),
sum((
case
when TellNumber not like '0%' then datediff(second,StartDateTime,EndDateTime)
else 0
end
))) as 市內通話,
sum((
case
when TellNumber like '0%' then datediff(second,StartDateTime,EndDateTime)
else 0
end
)) as 長途通話
from T_CallRecords
union all
select CallerNumber,TellNumber,datediff(second,StartDateTime,EndDateTime) as 通話時長
from T_CallRecords
--客戶和訂單表的練習
--建立一個客戶表
create table T_Customers(
id int not null,
name nvarchar(50) collate chinese_prc_ci_as null,
age int null
);
insert T_Customers(id,name,age) values(1,N'tom',10);
insert T_Customers(id,name,age) values(2,N'jerry',15);
insert T_Customers(id,name,age) values(3,N'john',22);
insert T_Customers(id,name,age) values(4,N'lily',18);
insert T_Customers(id,name,age) values(5,N'lucy',18);
select * from T_Customers
--建立一個銷售單表
create table T_Orders(
id int not null,
billno nvarchar(50) collate chinese_prc_ci_as null,
customerid int null);
insert T_Orders(id,billno,customerid)values(1,N'001',1)
insert T_Orders(id,billno,customerid)values(2,N'002',1)
insert T_Orders(id,billno,customerid)values(3,N'003',3)
insert T_Orders(id,billno,customerid)values(4,N'004',2)
insert T_Orders(id,billno,customerid)values(5,N'005',2)
insert T_Orders(id,billno,customerid)values(6,N'006',5)
insert T_Orders(id,billno,customerid)values(7,N'007',4)
insert T_Orders(id,billno,customerid)values(8,N'008',5)
select * from T_Orders
select o.billno,c.name,c.age
from T_Orders as o join T_Customers as c on o.customerid=c.id
--查詢訂單號,顧客名字,顧客年齡
select o.billno,c.name,c.age
from T_Orders as o join T_Customers as c on o.customerid=c.id
where c.age>15
--顯示年齡大于15歲的顧客姓名、年齡和訂單號
select o.billno,c.name,c.age
from T_Orders as o join T_Customers as c on o.customerid=c.id
where c.age>(select avg(age) from T_Customers)
--顯示年齡大于平均年齡的顧客姓名、年齡和訂單號
--子查詢練習
--新建一個數(shù)據(jù)庫,名為BookShop
Create database BookShop
--創(chuàng)建4張表
create table T_Reader(FId INT NOT NULL,FName varchar(50),FYearOfBirth INT,FCity varchar(50),FProvince varchar(50),FYearOfJoin INT);
create table T_Book(FId int not null,FName varchar(50),FYearPublished int,FCategoryId int);
create table T_Category(FId int not null,FName varchar(50));
create table T_ReaderFavorite(FCategoryId int,FReaderId int);
--分別為4張表插入數(shù)據(jù)
insert into T_Category(FId,FName) values(1,'Story');
insert into T_Category(FId,FName) values(2,'History');
insert into T_Category(FId,FName) values(3,'Theory');
insert into T_Category(FId,FName) values(4,'Technology');
insert into T_Category(FId,FName) values(5,'Art');
insert into T_Category(FId,FName) values(6,'Philosophy');
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(1,'Tom',1979,'TangShan','Hebei',2003);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(2,'Sam',1981,'LangFang','Hebei',2001);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(3,'Jerry',1966,'DongGuan','GuangDong',1995);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(4,'Lily',1972,'JiaXing','ZheJiang',2005);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(5,'Marry',1985,'BeiJing','BeiJing',1999);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(6,'Kelly',1977,'ZhuZhou','HuNan',1995);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(7,'Tim',1982,'YongZhou','HuNan',2001);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(8,'King',1979,'JiNan','ShanDong',1997);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(11,'John',1979,'QingDao','ShanDong',2003);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(9,'Lucy',1978,'LuoYang','HeNan',1996);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin) values(10,'July',1983,'ZhuMaDian','HeNan',1999);
insert into T_Reader(FId,FName,FYearOfBirth,FCity,fProvince,FyearOfJoin) values(12,'Fige',1981,'JinCheng','ShanXi',2003);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(1,'About J2EE',2005,4);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(2,'Learning Hibernate',2003,4);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(3,'Tow Cites',1999,1);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(4,'Jane Eyre',2001,1);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(5,'Oliver Twist',2002,1);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(6,'History of China',1982,2);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(7,'History of England',1860,2);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(8,'History of America',1700,2);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(9,'History of The Vorld',2008,2);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(10,'Atom',1930,3);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(11,'RELATIVITY',1945,3);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(12,'Computer',1970,3);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(13,'Astronomy',1971,3);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(14,'How To singing',1771,5);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(15,'DaoDeJing',2001,6);
insert into T_Book(FId,FName,FYearPublished,FCategoryId) values(16,'Obedience to Au',1995,6);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(1,1);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(5,2);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(2,3);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(3,4);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(5,5);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(1,6);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(1,7);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(4,8);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(6,9);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(5,10);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(2,11);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(2,12);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(1,12);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(3,1);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(1,3);
insert into T_ReaderFavorite(FCategoryId,FReaderId) values(4,4);
select * from T_Book
select * from T_Category
select * from T_Reader
select * from T_ReaderFavorite
--并列查詢
select 1 as f1,2,(select MIN(FYearPublished) from T_Book),
(select MAX(FYearPublished) from T_Book) as f4
--查詢入會日期在2001或者2003年的讀者信息
select * from T_Reader
where FYearOfJoin in (2001,2003)
--與between...and不同
select * from T_Reader
where FYearOfJoin between 2001 and 2003
--查詢有書出版的年份入會的讀者信息
select * from T_Reader
where FYearOfJoin in
(
select FYearPublished from T_Book
)
--SQL Server 2005之后的版本內置函數(shù):ROW_NUMBER(),稱為開窗函數(shù),可以進行分頁等操作。
select ROW_NUMBER() over(order by FSalary DESC) as Row_Num,
FNumber,FName,FSalary,FAge from T_Employee
--特別注意,開窗函數(shù)row_number()只能用于select或order by 子句中,不能用于where子句中
--查詢第3行到第5行的數(shù)據(jù)
select * from
(
select ROW_NUMBER() over(order by FSalary DESC) as Row_Num,
FNumber,FName,FSalary,FAge from T_Employee
) as e1
where e1.Row_Num>=3 and e1.Row_Num<=5
四、SQL其他概念
--索引
1、什么是索引?優(yōu)缺點是什么?
索引是對數(shù)據(jù)庫表中一列或多列的值進行排序的一種單獨的、物理的數(shù)據(jù)庫結構。
優(yōu)點:
1) 大大加快數(shù)據(jù)的檢索速度;
2) 創(chuàng)建唯一性索引,保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性;
3) 加速表和表之間的連接;
4) 在使用分組和排序子句進行數(shù)據(jù)檢索時,可以顯著減少查詢中分組和排序的時間。
缺點:
1) 索引需要占物理空間;
2) 當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)的維護,降低了數(shù)據(jù)的維護速度。
--創(chuàng)建索引,在列上點擊右鍵,寫一個名稱,選定列即可。
2、業(yè)務主鍵和邏輯主鍵
業(yè)務主鍵是使用有業(yè)務意義的字段做主鍵,比如身份證號,銀行賬號等;
邏輯主鍵是使用沒有任何業(yè)務意義的字段做主鍵。因為很難保證業(yè)務主鍵不會重復(身份證號重復)、不會變化(賬號升位),因此推薦使用邏輯主鍵。
3、SQL Server 兩種常用的主鍵數(shù)據(jù)類型
1) int(或 bigint) + 標識列(又稱自動增長字段)
用標識列實現(xiàn)字段自增可以避免并發(fā)等問題,不要開發(fā)人員控制自增。用標識列的字段在Insert的時候不用指定主鍵的值。
優(yōu)點:占用空間小、無需開發(fā)人員干預、易讀;
缺點:效率低,數(shù)據(jù)導入導出的時候很痛苦。
設置:"修改表"->選定主鍵->"列屬性"->"標識規(guī)范"選擇"是"
2) uniqueidentifier(又稱GUID、UUID)
GUID算法是一種可以產生唯一表示的高效算法,它使用網卡MAC、地址、納秒級時間、芯片ID碼等算出來的,這樣保證每次生成的GUID永遠不會重復,無論是同一計算機還是不同計算機。在公元3400年前產生的GUID與任何其他產生過的GUID都不相同。
SQL Server中生成GUID的函數(shù)newid()。
優(yōu)點:效率高、數(shù)據(jù)導入導出方便;
缺點:占用空間大、不易讀。
業(yè)界主流傾向于使用GUID。
寫在后面:看著洋洋灑灑的一大篇,除了一些常識性的東西和涉及到數(shù)據(jù)庫的增刪改查之外,其實沒什么新鮮東西,但判斷一個程序員水平的高低不僅是做過多么大的一個項目,更是對基礎知識的掌握程度。