zoukankan      html  css  js  c++  java
  • sql server基础

    一、SQL基础知识

    1DDL(数据定义语言)

    1)创建数据表

    --创建数据表

    createtable Test(Id intnotnull, Age char(20))

    --创建数据表

    createtable T_Person1(Id intnotnull,

    Name nvarchar(50),

    Age intnull)

    --创建表,添加外键

    Createtable T_Students(

    StudentNo char(4),

    CourseNo char(4),

    Score int,

    Primarykey(StudentNo),

    Foreignkey(CourseNo)References T_Course(CourseNo)

    );

    2)修改表结构

    --修改表结构,添加字段

    Altertable T_Person add NickName nvarchar(50)null;

    --修改表结构,删除字段

    Altertable T_Person Drop NickName;

    3)删除数据表

    --删除数据表

    Droptable T_Person;

    --删除数据表

    droptable test

    4)创建索引

    Create[Unique]Index<索引名>on<基本表名>(<列明序列>);

    2DML(数据操纵语言)

    1)插入语句

    insertinto T_Person1(Id,Name,Age)values(1,'Vicky',20)

    --插入一条据数,字段和值必须前后对应

    insertinto T_Preson1(Id,Name,Age)values(2,'Tom',19)

    insertinto T_Person1(Id,Name,Age)values(4,'Jim',19)

    insertinto T_Person1(Id,Name,Age)values(5,'Green',20)

    insertinto T_Person1(Id,Name,Age)values(6,'Hanmeimei',21)

    insertinto T_Person1(Id,Name,Age)values(7,'Lilei',22)

    insertinto T_Person1(Id,Name,Age)values(8,'Sky',23)

    insertinto 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,以防出现乱码

    update T_Person1 set Name=N'成年人'where Age=30or Age=50

    3)删除语句

    deletefrom T_Person1

    --删除表中全部数据

    deletefrom T_Person1 where Name='Tom'

    --根据条件删除数据

    4)查询语句

    查询语句非常强大,几乎可以查任意东西!

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

    ---- 数据检索 -----

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

    --查询不与任何表关联的数据.

    SELECT1+1; --简单运算
    select
    1+2as
    结果

    SELECTnewid();--查询一个GUID字符创

    selectGETDATE()as日期--查询日期

    --可以查询SQLServer版本

    select @@VERSION as SQLServer版本

    --一次查询多个

    select1+1结果,GETDATE()as日期, @@VERSION as版本,NEWID()as编号

    --简单的数据查询.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;

    --对表记录进行排序,默认排序规则是ASC

    SELECT*FROM T_Employee ORDERBY FAge ASC,FSalary DESC;

    --ORDER BY 子句要放在 WHERE 子句之后.

    SELECT*FROM T_Employee WHERE FAge>23ORDERBY FAge DESC,FSalary DESC;

    --WHERE 中可以使用的逻辑运算符:orandnot<>=>=<=!=<>.

    --模糊匹配,首字母未知.

    SELECT*FROM T_Employee WHERE FName LIKE'_arry';

    --模糊匹配,前后多个字符未知.

    SELECT*FROM T_Employee WHERE FName LIKE'%n%';

    --NULL 表示"不知道",有 NULL 参与的运算结果一般都为 NULL.

    --查询数据是否为 NULL,不能用 = != <>,要用IS关键字

    SELECT*FROM T_Employee WHERE FName ISNULL;

    SELECT*FROM T_Employee WHERE FName ISNOTNULL;

    --查询在某个范围内的数据,IN 表示包含于,IN后面是一个集合

    SELECT*FROM T_Employee WHERE FAge IN(23,25,28);

    --下面两条查询语句等价。

    SELECT*FROM T_Employee WHERE FAge>=23AND FAge<=30;

    SELECT*FROM T_Employee WHERE FAge BETWEEN23AND30;

    ----创建一张Employee表,以下几个Demo中会用的这张表中的数据

    ----SQL管理器中执行下面的SQL语句,在T_Employee表中进行练习

    createtable T_Employee(FNumber varchar(20),

    FName varchar(20),

    FAge int,

    FSalary Numeric(10,2),

    primarykey(FNumber)

    )

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('DEV001','Tom',25,8300)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('DEV002','Jerry',28,2300.83)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('SALES001','Lucy',25,5000)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('SALES002','Lily',25,6200)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('SALES003','Vicky',25,1200)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('HR001','James',23,2200.88)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('HR002','Tom',25,5100.36)

    insertinto T_Employee(FNumber,FName,FAge,FSalary)values('IT001','Tom',28,3900)

    insertinto 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

    --可更改显示列名的关键字asas—起别名

    select FName as姓名,FAge as年龄,FSalary as薪水from T_Employee

    二、SQLServer 中的数据类型

    1精确数字类型

    bigint

    int

    smallint

    tinyint

    bit

    money

    smallmoney

    2字符型数据类型MS建议用VarChar(max)代替Text

    Char

    VarChar

    Text

    3近似数字类型

    Decimal

    Numeric

    Real

    Float

    4Unicode字符串类型

    Nchar

    NvarChar

    Ntext

    5二进制数据类型,MS建议VarBinary(Max)代替Image数据类型,max=231-1

    Binary(n)存储固定长度的二进制数据

    VarBinary(n)存储可变长度的二进制数据,范围在n~(1,8000)

    Image 存储图像信息

    6日期和时间类型,数据范围不同,精确地不同

    DateTime

    SmallDateTime

    7特殊用途数据类型

    Cursor

    Sql-variant

    Table

    TimeStamp

    UniqueIdentifier

    XML

    三、SQL中的内置函数

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

    ----- 数据汇总-聚合函数---------

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

    --查询T_Employee表中数据条数

    selectCOUNT(*)from T_Employee

    --查询工资最高的人

    selectMAX(FSalary)as Top1 from T_Employee

    --查询工资最低的人

    selectMin(FSalary)as Bottom1 from T_Employee

    --查询工资的平均水平

    selectAvg(FSalary)as平均水平from T_Employee

    --所有工资的和

    selectSUM(FSalary)as总工资from T_Employee

    --查询工资大于5K的员工总数

    selectCOUNT(*)as total from T_Employee

    where FSalary>5000

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

    ----- 数据排序-------

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

    --按年龄排序升序,默认是升序

    select*from T_Employee

    orderby FAge ASC

    --多个条件排序,先什么,后什么,在前一个条件相同的情况下,根据后一个条件进行排列

    --whereorder by之前

    select*from T_Employee

    orderby 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

    selectnull+1

    --查询名字是null的数据

    select*from T_Employee

    where FName isnull

    --查询名字不为空null的数据

    select*from T_Employee

    where FName isnotnull

    --年龄是23,25,28中的员工

    select*from T_Employee

    where FAge=23or FAge=25or FAge=28

    --或者用in 集合查询

    --年龄是23,25,28中的员工

    select*from T_Employee

    where FAge in(23,25,28)

    --年龄在2025之间的员工信息

    select*from T_Employee

    where FAge>20and FAge<25

    --年龄在2025之间的员工信息,包含25

    select*from T_Employee

    where FAge between20and25

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

    ----- 数据分组-------

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

    Select FAge,COUNT(*)from T_Employee

    groupby FAge

    --1.根据年龄进行分组

    --2.再取出分组后的年龄的个数

    --注意:没有出现在group by 子句中的字段,不能出现在select语句后的列名列表中(聚合函数除外)

    --group by 必须出现在where后面

    Select FAge,AVG(FSalary),COUNT(*)from T_Employee

    groupby FAge

    --错误用法

    Select FAge,FName,COUNT(*)from T_Employee

    groupby FAge

    --加上wheregroup by 子句

    --group by 必须出现在where后面

    Select FAge,AVG(FSalary),COUNT(*)from T_Employee

    where FAge>=25

    groupby FAge

    --Having不能包含查不到的字段,只能包含聚合函数和本次查询有关的字段

    select FAge,COUNT(*)from T_Employee

    groupby FAge

    HavingCOUNT(*)>1

    select FAge,COUNT(*)from T_Employee

    where FSalary>2500

    groupby FAge

    --HAVING 子句中的列 'T_Employee.FSalary' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中

    --Having是对分组后信息的过滤,能用的列和select中能有的列是一样的。

    --因此,having不能代替where

    select FAge,COUNT(*)from T_Employee

    groupby FAge

    Having FSalary>2500

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

    ----- 确定结果集行数-------

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

    --取出所有员工的信息,根据工资降序排列

    select*from T_Employee

    orderby FSalary DESC

    --取出前三名员工的信息,根据工资降序排列

    select top 3*from T_Employee

    orderby FSalary DESC

    --根据工资取出排名在6-8的员工信息,按工资降排列

    select top 3*from T_Employee

    where FNumber notin

    (select top 5 FNumber from T_Employee orderby FSalary DESC)

    orderby FSalary DESC

    ---修改数据表,添加字段,更新字段的值等操作。

    altertable T_Employee add FSubCompany varchar(20)

    altertable 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

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

    ------ 去掉重复数据------

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

    --所有员工的部门信息

    selectDistinct FDepartment from T_Employee;

    select FDepartment,FSubCompany

    from T_Employee

    --以上两个例子结合起来比较,Distinct针对的是整行进行比较的

    selectDistinct FDepartment,FSubCompany

    from T_Employee

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

    ----- 联合结果集Union --------

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

    --创建一个测试表T_TempEmployee,并插入数据

    CreateTable T_TempEmployee(FIdCardNumber varchar(20),FName varchar(20),FAge int,Primarykey(FIdCardNumber));

    insertinto T_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890121','Sarani',33);

    insertinto T_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890122','Tom',26);

    insertinto T_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890123','Yamaha',38);

    insertinto T_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890124','Tina',36);

    insertinto T_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890125','Konkaya',29);

    insertinto T_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890126','Foortia',29);

    select*from T_TempEmployee

    --Union关键字,联合2个结果

    --2个查询结果结合为1个查询结果

    --要求:上下2个查询语句的字段(个数,名字,类型相容)必须一致

    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:不合并重复数据

    --Union:合并重复数据

    select FName,FAge from T_Employee

    unionall

    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

    unionall

    select'正式员工最低年龄',MIN(FAge)from T_Employee

    unionall

    select'临时工最高年龄',MAX(FAge)from T_TempEmployee

    unionall

    select'临时工最低年龄',MIN(FAge)from T_TempEmployee

    --查询每位正式员工的信息,包括工号,工资,并且在最后一行加上员工工资额合计

    select FNumber,FSalary from T_Employee

    unionall

    select'工资额合计',SUM(FSalary)from T_Employee

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

    ----- SQL其他内置函数------

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

    --1.数学函数

    --ABS():求绝对值

    --CEILING():舍入到最大整数

    --FLOOR():舍入到最小整数

    --ROUND():四舍五入

    selectABS(-3)

    selectCEILING(3.33)

    selectCEILING(-3.61)

    selectFLOOR(2.98)

    selectFLOOR(-3.61)

    selectROUND(-3.61,1)--第二个参数是精度,小数点后的位数

    selectROUND(-3.61,0)

    selectROUND(3.1415926,3)

    --2.字符串函数

    --LEN():计算字符串长度

    --LOWER(),UPPER():转大小写

    --LTRIM():去掉字符串左侧的空格

    --RTRIM():去掉字符串右侧的空格

    --SUBSTRING(string,start_positoin,length):

    --索引从1开始

    selectSUBSTRING('abc111',2,3)--结果是bc1

    select FName,SUBSTRING(FName,2,2)from T_Employee

    selectLEN('abc') --结果是3

    select FName,LEN(FName)from T_Employee

    --没有可以同时既去掉左边空格、又去掉右边空格的TRIM()内置函数,所以先左后右的进行TRim,当然,你也可以先右后左

    selectLTRIM(' abc '),RTRIM(' abc '),LEN(LTRIM(RTRIM(' abc ')))

    --3.日期函数

    --GETDATE():获取当前日期时间

    --DATEADD(datepart,numbre,date):计算增加以后的日期,

    --参数date为待计算的日期;参数number为增量;参数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 一年的日数,一年中的第几日 1-366

    Day Dd d 日,1-31

    Weekday Dw w 一周的日数,一周中的第几日 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

    */

    selectDATEADD(DAY,3,getdate())

    selectDATEADD(MONTH,-3,getdate())

    selectDATEADD(HOUR,8,getdate())

    selectDATEDIFF(YEAR,'1989-05-01',GETDATE())

    selectDATEDIFF(HH,GETDATE(),DATEADD(DAY,-3,GETDATE()))

    --查询员工的工龄,年为单位

    select FName,FInDate,DATEDIFF(year,FInDate,getdate())as工龄from T_Employee

    --取出每一年入职员工的个数V1

    selectDATEDIFF(year,FInDate,getdate()),COUNT(*)

    from T_Employee

    groupbyDATEDIFF(year,FInDate,getdate())

    --取出每一年入职员工的个数V2

    selectDATEPART(YEAR,FInDate),COUNT(*)

    from T_Employee

    groupbyDATEPART(YEAR,FInDate)

    selectDATEPART(YEAR,GETDATE())

    selectDATEPART(MONTH,GETDATE())

    selectDATEPART(DAY,GETDATE())

    selectDATEPART(HH,GETDATE())

    selectDATEPART(MINUTE,GETDATE())

    selectDATEPART(SECOND,GETDATE())

    --4.类型转换函数

    --CAST(expression as data_type)

    --CONVERT(data_type,expression)

    selectCAST('123'asint),CAST('2010-09-08'as datetime),

    CONVERT(datetime,'2010-09-08'),CONVERT(varchar(20),123)

    --5.空值处理函数isNull

    --ISNULL(expression,value)

    selectISNULL(FName,'佚名')as姓名from T_Employee

    --6.CASE函数用法:

    --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

    when1then'普通客户'

    when2then'会员'

    when3then'VIP'

    else'未知客户类型'

    End

    )as客户类型

    from T_Customer

    --收入水平查询

    select FName,

    (

    case

    when FSalary <2000then'低收入'

    when FSalary >=2000and FSalary <=5000then'中等收入'

    else'高收入'

    end

    )as收入水平

    from T_Employee

    --这里有一道关于CASE用法的面试题

    --T中有ABC三列,用SQL语句实现: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>0then FAmount

    else0

    end

    )as收入,

    (

    case

    when FAmount<0thenABS(FAmount)

    else0

    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''

    createtable T_Scores(

    [Date] datetime nullcollate

    [Name] nvarchar(50)

    )

    CREATETABLE[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

    --列出第一个表格

    --统计每支队伍的胜负情况

    select Name,

    (

    case Score

    when N''then1

    else0

    end

    )as,

    (

    case Score

    when N''then1

    else0

    end

    )as

    from T_Scores

    select Name,

    sum

    (

    case Score

    when N''then1

    else0

    end

    )as,

    sum

    (

    case Score

    when N''then1

    else0

    end

    )as

    from T_Scores

    groupby Name

    --根据每个队的胜负判断出胜负的场数

    --5) 创建一张表,记录电话呼叫员的工作流水,记录呼叫员编号,对方号码,通话开始时间,通话结束时间,。

    --创建一张表T_Callers,记录电话呼叫员的工作流水,记录呼叫员编号、对方号码、通话开始时间、通话结束时间。建表、插数据等最后都自己写SQL语句。

    --要求:

    -- 1) 输出所有数据中通话时间最长的5条记录。

    -- 2) 输出所有数据中拨打长途号码(对方号码以0开头)的总时长。

    -- 3) 输出本月通话总时长最多的前三个呼叫员的编号。

    -- 4) 输出本月拨打电话次数最多的前三个呼叫员的编号。

    -- 5) 输出所有数据的拨号流水,并且在最后一行添加总呼叫时长。

    -- 记录呼叫员编号、对方号码、通话时长

    -- ......

    -- 汇总[市内号码总时长][长途号码总时长]

    --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

    -- 创建表

    createtable T_CallRecords(

    id intnotnull,

    CallerNumber varchar(3),

    TellNumber varchar(13),

    StartDateTIme datetime,

    EndDateTime datetime,

    Primarykey(Id)

    );

    --插入数据

    insertinto T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTIme)

    values(1,'001','02088888888','2010-7-10 10:01','2010-7-10 10:05');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(2,'002','02088888888','2010-7-11 13:41','2010-7-11 13:52');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(3,'003','89898989','2010-7-11 14:42','2010-7-11 14:49');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(4,'004','02188368981','2010-7-13 21:04','2010-7-13 21:18');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(5,'005','76767676','2010-6-29 20:15','2010-6-29 20:30');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(6,'006','02288878243','2010-7-15 13:40','2010-7-15 13:56');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(7,'007','67254686','2010-7-13 11:06','2010-7-13 11:19');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(8,'008','86231445','2010-6-19 19:19','2010-6-19 19:25');

    INSERTINTO T_CallRecords(Id,CallerNumber,TellNumber,StartDateTime,EndDateTime)

    VALUES(9,'009','87422368','2010-6-19 19:25','2010-6-19 19:36');

    INSERTINTO 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;

    --数据汇总

    select*from T_CallRecords

    -- 1)输出所有数据中通话时间最长的5条记录。

    --@计算通话时间;

    --@按通话时间降序排列;

    --@取前5条记录。

    select top 5 CallerNumber,DATEDIFF(SECOND,StartDateTime,EndDateTime)as总时长

    from T_CallRecords

    orderbyDATEDIFF(SECOND,StartDateTime,EndDateTime)DESC

    -- 2):输出所有数据中拨打长途号码(对方号码以0开头)的总时长

    --@查询拨打长途号码的记录;

    --@计算各拨打长途号码的通话时长;

    --@对各拨打长途号码的通话时长进行求和。

    selectSUM(DATEDIFF(SECOND,StartDateTime,EndDateTime))as总时长from T_CallRecords

    where TellNumber like'0%'

    -- 3):输出本月通话总时长最多的前三个呼叫员的编号。

    --@按呼叫员编号进行分组;

    --@计算各呼叫员通话总时长;

    --@按通话总时长进行降序排列;

    --@查询前3条记录中呼叫员的编号。

    selectdatediff(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

    wheredatediff(month,StartDateTime,getdate())=12--一年前的

    groupby CallerNumber

    orderbySUM(DATEDIFF(SECOND,StartDateTime,EndDateTime))DESC

    -- 4) 输出本月拨打电话次数最多的前三个呼叫员的编号.

    --@按呼叫员编号进行分组;

    --@计算个呼叫员拨打电话的次数;

    --@按呼叫员拨打电话的次数进行降序排序;

    --@查询前3条记录中呼叫员的编号。

    select top 3 CallerNumber,count(*)

    from T_CallRecords

    wheredatediff(month,StartDateTime,getdate())=12--一年前的

    groupby CallerNumber

    orderbycount(*)DESC

    --5) 输出所有数据的拨号流水,并且在最后一行添加总呼叫时长:

    -- 记录呼叫员编号、对方号码、通话时长

    -- ......

    -- 汇总[市内号码总时长][长途号码总时长]

    --@计算每条记录中通话时长;

    --@查询包含不加 0 号码,即市内号码的记录;

    --@计算市内号码通话总时长;

    --@查询包含加 0 号码,即长途号码的记录;

    --@计算长途号码通话总时长;

    --@联合查询。

    select'汇总'as汇总,

    convert(varchar(20),

    sum((

    case

    when TellNumber notlike'0%'thendatediff(second,StartDateTime,EndDateTime)

    else0

    end

    )))as市内通话,

    sum((

    case

    when TellNumber like'0%'thendatediff(second,StartDateTime,EndDateTime)

    else0

    end

    ))as长途通话

    from T_CallRecords

    unionall

    select CallerNumber,TellNumber,datediff(second,StartDateTime,EndDateTime)as通话时长

    from T_CallRecords

    --客户和订单表的练习

    --建立一个客户表

    createtable T_Customers(

    id intnotnull,

    name nvarchar(50)collate chinese_prc_ci_as null,

    age intnull

    );

    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

    --建立一个销售单表

    createtable T_Orders(

    id intnotnull,

    billno nvarchar(50)collate chinese_prc_ci_as null,

    customerid intnull);

    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>(selectavg(age)from T_Customers)

    --显示年龄大于平均年龄的顾客姓名、年龄和订单号

    --子查询练习

    --新建一个数据库,名为BookShop

    Create database BookShop

    --创建4张表

    createtable T_Reader(FId INTNOTNULL,FName varchar(50),FYearOfBirth INT,FCity varchar(50),FProvince varchar(50),FYearOfJoin INT);

    createtable T_Book(FId intnotnull,FName varchar(50),FYearPublished int,FCategoryId int);

    createtable T_Category(FId intnotnull,FName varchar(50));

    createtable T_ReaderFavorite(FCategoryId int,FReaderId int);

    --分别为4张表插入数据

    insertinto T_Category(FId,FName)values(1,'Story');

    insertinto T_Category(FId,FName)values(2,'History');

    insertinto T_Category(FId,FName)values(3,'Theory');

    insertinto T_Category(FId,FName)values(4,'Technology');

    insertinto T_Category(FId,FName)values(5,'Art');

    insertinto T_Category(FId,FName)values(6,'Philosophy');

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(1,'Tom',1979,'TangShan','Hebei',2003);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(2,'Sam',1981,'LangFang','Hebei',2001);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(3,'Jerry',1966,'DongGuan','GuangDong',1995);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(4,'Lily',1972,'JiaXing','ZheJiang',2005);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(5,'Marry',1985,'BeiJing','BeiJing',1999);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(6,'Kelly',1977,'ZhuZhou','HuNan',1995);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(7,'Tim',1982,'YongZhou','HuNan',2001);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(8,'King',1979,'JiNan','ShanDong',1997);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(11,'John',1979,'QingDao','ShanDong',2003);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(9,'Lucy',1978,'LuoYang','HeNan',1996);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,FProvince,FyearOfJoin)values(10,'July',1983,'ZhuMaDian','HeNan',1999);

    insertinto T_Reader(FId,FName,FYearOfBirth,FCity,fProvince,FyearOfJoin)values(12,'Fige',1981,'JinCheng','ShanXi',2003);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(1,'About J2EE',2005,4);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(2,'Learning Hibernate',2003,4);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(3,'Tow Cites',1999,1);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(4,'Jane Eyre',2001,1);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(5,'Oliver Twist',2002,1);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(6,'History of China',1982,2);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(7,'History of England',1860,2);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(8,'History of America',1700,2);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(9,'History of The Vorld',2008,2);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(10,'Atom',1930,3);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(11,'RELATIVITY',1945,3);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(12,'Computer',1970,3);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(13,'Astronomy',1971,3);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(14,'How To singing',1771,5);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(15,'DaoDeJing',2001,6);

    insertinto T_Book(FId,FName,FYearPublished,FCategoryId)values(16,'Obedience to Au',1995,6);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(1,1);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(5,2);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(2,3);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(3,4);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(5,5);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(1,6);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(1,7);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(4,8);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(6,9);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(5,10);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(2,11);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(2,12);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(1,12);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(3,1);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(1,3);

    insertinto T_ReaderFavorite(FCategoryId,FReaderId)values(4,4);

    select*from T_Book

    select*from T_Category

    select*from T_Reader

    select*from T_ReaderFavorite

    --并列查询

    select1as f1,2,(selectMIN(FYearPublished)from T_Book),

    (selectMAX(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 between2001and2003

    --查询有书出版的年份入会的读者信息

    select*from T_Reader

    where FYearOfJoin in

    (

    select FYearPublished from T_Book

    )

    --SQL Server 2005之后的版本内置函数:ROW_NUMBER(),称为开窗函数,可以进行分页等操作。

    selectROW_NUMBER() over(orderby FSalary DESC)as Row_Num,

    FNumber,FName,FSalary,FAge from T_Employee

    --特别注意,开窗函数row_number()只能用于selectorder by 子句中,不能用于where子句中

    --查询第3行到第5行的数据

    select*from

    (

    selectROW_NUMBER() over(orderby FSalary DESC)as Row_Num,

    FNumber,FName,FSalary,FAge from T_Employee

    )as e1

    where e1.Row_Num>=3and e1.Row_Num<=5

    四、SQL其他概念

    --索引

    1什么是索引?优缺点是什么?

    索引是对数据库表中一列或多列的值进行排序的一种单独的、物理的数据库结构。

    优点:

     1)大大加快数据的检索速度;

     2)创建唯一性索引,保证数据库表中每一行数据的唯一性;

     3)加速表和表之间的连接;

     4)在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。

    缺点:

     1)索引需要占物理空间;

     2)当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。

    --创建索引,在列上点击右键,写一个名称,选定列即可。

    2业务主键和逻辑主键

    业务主键是使用有业务意义的字段做主键,比如身份证号,银行账号等;

    逻辑主键是使用没有任何业务意义的字段做主键。因为很难保证业务主键不会重复(身份证号重复)、不会变化(账号升位),因此推荐使用逻辑主键。

    3SQL Server 两种常用的主键数据类型

    1)int( bigint)+标识列(又称自动增长字段)

    用标识列实现字段自增可以避免并发等问题,不要开发人员控制自增。用标识列的字段在Insert的时候不用指定主键的值。

    优点:占用空间小、无需开发人员干预、易读;

    缺点:效率低,数据导入导出的时候很痛苦。

    设置:"修改表"->选定主键->"列属性"->"标识规范"选择""

    2) uniqueidentifier(又称GUIDUUID)

    GUID算法是一种可以产生唯一表示的高效算法,它使用网卡MAC、地址、纳秒级时间、芯片ID码等算出来的,这样保证每次生成的GUID永远不会重复,无论是同一计算机还是不同计算机。在公元3400年前产生的GUID与任何其他产生过的GUID都不相同。

    SQL Server中生成GUID的函数newid()

    优点:效率高、数据导入导出方便;

    缺点:占用空间大、不易读。

    业界主流倾向于使用GUID

  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/lmfeng/p/2131685.html
Copyright © 2011-2022 走看看