先创建一个工资表
create table 工资表
(
编号 int identity (1,1) not null,
姓名 nvarchar(10) not null,
身份证号 varchar(18) primary key,
职务 nvarchar(30) not null,
出生日期 datetime not null,
基本工资 money not null,
备注 nvarchar(1000),
)
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资)
values ('张三','10086','DBA','1995/3/3','10000')
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资)
values ('李四','20086','运维工程师','1992/2/2','9000')
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资,备注)
values ('王五','22286','运维经理','1990/5/5','15000','技术全面')
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资)
values ('孙七','33386','运维工程师','1995/1/1','8000')
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资)
values ('赵六','66086','运维总监','1980/7/7','36000')
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资)
values ('张嘴','66686','DBA','1989/6/6','9000')
insert into [工资表](姓名,身份证号,职务,出生日期,基本工资,备注)
values ('王者','88086','CTO','1975/11/11','55000','项目经验丰富')
查询 工资表 中所有员工信息:
select * from [工资表]
系统函数用来获取有关 SQL Server 中对象和设置的系统信息。
函数名 | 描述 |
---|---|
CONVERT() | 数据类型转换 |
CAST() | 数据类型转换,与 CONVERT 相比语法比较简单,转换功能较少 |
CURRENT_USER() | 返回当前登录的数据库用户名 |
DATALENGTH() | 返回用于指定表达式的字节数 |
HOST_NAME() | 返回当前用户所登录的计算机的名称 |
SYSTEM_USER() | 返回当前登录系统用户名 |
USER_NAME() | 从给定的用户 ID 中返回数据库用户名 |
字符串函数用于控制返回给用户的字符串,这些功能仅用于字符型数据。
函数名 | 描述 |
---|---|
CHARINDEX() | 用来寻找一个指定的字符串在另一个字符串中的起始位置 |
LEN() | 返回传递给它的字符串长度 |
UPPER() | 把转递给它的字符串转换为大写 |
LTRIM() | 清除字符左边的空格 |
RTRIM() | 清除字符右边的空格 |
RIGHT() | 替换一个字符串中的字符 |
STUFF() | 在一个字符串中,删除指定位置指定长度的字符串,并在该位置插入一个新的1字符串 |
将 工资表 中所有运维工程师的姓名和基本工资组合:
select '运维工程师 '+姓名+' 的基本工资是:'+CAST(基本工资 as varchar(10))+'元'
from [工资表]
where 职务='运维工程师'
在 SQL Server 中不能直接对日期运用数学函数,需要使用日期函数操作日期值。日期函数帮助提取日期值中的日、月及年,以便分别操作它们。
函数名 | 描述 |
---|---|
GETDATE() | 取得当前的系统日期 |
DATEADD() | 添加指定的年(YY)、月(MM)、或日(DD) |
DATEDIFF() | 比较两个日期之间的指定日期部分的差 |
DATENAME() | 显示指定日期中特定部分的字符串 |
DATEPART() | 显示日期中指定日期部分的整数形式 |
显示距离当前 10 天之后的日期和时间:
select DATEADD (DD,10,GETDATE())
select 姓名,DATEDIFF(YY,出生日期,GETDATE()) AS 年龄 from [工资表]
select 姓名,DATENAME(YEAR,出生日期) AS 出生年份
from [工资表]
where 出生日期 BETWEEN '1990-01-01' AND '1999-12-31'
在查询时还会经常碰到的是取某些列的最大值、最小值、平均值等信息,有时候还需要计算出究竟查询到多少行数据项。这个时候就可以使用聚合函数,因为聚合函数能够基于列进行计算,并返回单个值。
常用的聚合函数有SUM()、AVG()、MAX()、MIN()、COUNT()。
查询 工资表 中所有员工基本工资的总和:
select SUM(基本工资) AS 总工资 from [工资表]
select AVG(基本工资) AS 平均工资 from [工资表]
select MAX(基本工资) AS 最高工资,MIN(基本工资) AS 最低工资 from [工资表]
select COUNT(*) AS 总行数 from [工资表]
select COUNT(出生日期) AS '90后人数'
from [工资表]
where 出生日期>='1990-01-01'
分组查询就是将表中的数据通过 GROUP BY 子句分类组合,再根据需要得到统计信息。如果需要对分组结果进行筛选,只显示满足条件的组,需要使用 HAVING 子句。
查询 工资表 中每个职务的平均工资:
select 职务,AVG(基本工资) AS 职务平均工资 from [工资表] GROUP BY 职务
在使用 GROUP BY 关键字时,在 SELECT 列表中可以指定的项目有限的,SELECT 语句中仅允许以下几项:
select 职务,AVG(基本工资) AS 职务平均工资 from [工资表] GROUP BY 职务
HAVING AVG(基本工资)<10000
当 GROUP BY 子句使用 HAVING 子句时,查询结果只返回满足 HAVING 条件的组。HAVING 子句与 WHERE 子句类似,均用于设置限制条件。但 HAVING 子句和 WHERE 子句的作用有如下区别:
当 WHERE 和 HAVING 同在一个 SELECT 语句中使用时,执行顺序为 WHERE——》GROUP BY——》HAVING。
查询 工资表 中平均工资小于 10000 的职务,前提是员工 张三 不计算在内:
select 职务,AVG(基本工资) AS 职务总工资 from [工资表]
where 姓名 != '张三'
GROUP BY 职务
HAVING AVG(基本工资)<10000
数学函数用于对数值进行代数运算。
函数名 | 描述 |
---|---|
ABS() | 取数值表达式的绝对值 |
CEILING() | 取大小或等于指定数值、表达式的最小整数 |
FLOOR() | 取小数或等于指定表达式的最大整数 |
[POWER() | 取数值表达式的幂值 |
ROUND() | 将数值表达式四舍五入为指定精度 |
SIGN() | 对于正数返回+1,对于负数返回-1,对于0则返回0 |
SQRT() | 取浮点表达式的平方根 |
查询 工资表 中所有人平均工资,用CEILING()取整:
select CEILING(AVG(基本工资)) AS 平均工资 from [工资表]
在实际生产环境中可以根据需要,将函数进行不同的组合,以满足实际需求。
查询未满 30 岁的员工的生日和年龄,并计算出距离 30 岁的天数,最后用字符串拼接显示结果:
1. 查询正确数据结果
select 姓名,出生日期,DATEDIFF(YY,出生日期,GETDATE()) AS 年龄,DATEDIFF(DD,GETDATE(),DATEADD(YY,30,出生日期)) AS 距离30岁天数
from [工资表]
where DATEDIFF(YY,出生日期,GETDATE())<=30 and 姓名!='王五'
ORDER BY 出生日期
select
'员工 '+姓名+
' 的生日是'+CONVERT(varchar(10),出生日期,111)+
',现在年龄是 '+CAST(DATEDIFF(YY,出生日期,GETDATE()) AS varchar(10))+'岁'+
',距离30岁生日还有 '+
CAST(DATEDIFF(DD,GETDATE(),DATEADD(YY,30,出生日期)) AS varchar(10))+'天'
from [工资表]
where DATEDIFF(YY,出生日期,GETDATE())<=30 and 姓名!='王五'
ORDER BY 出生日期
如果一个查询需要对多个表进行操作,就称为联接查询,联接查询的结果集或结果称为表之间的联接。联接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征。
先创建两个表:
create table A
(
姓名 nvarchar(10) not null,
学校 nvarchar(20) not null,
)
create table B
(
姓名 nvarchar(10) not null,
职业 nvarchar(20) not null,
)
insert into A (姓名,学校) values ('张三','清华大学')
insert into A (姓名,学校) values ('李四','北京大学')
insert into A (姓名,学校) values ('王五','武汉大学')
insert into A (姓名,学校) values ('孙七','985大学')
insert into A (姓名,学校) values ('老八','211大学')
往 B 表 写入 数据:
insert into B (姓名,职业) values ('张三','咨询师')
insert into B (姓名,职业) values ('李四','律师')
insert into B (姓名,职业) values ('老八','作家')
insert into B (姓名,职业) values ('小明','明星')
insert into B (姓名,职业) values ('小黑','保安')
表联接类型可以分为内联接、外联接和交叉联接等。
内联接(inner join)是最常用的一种联接方式,只返回两个数据集合之间匹配关系的行,将位于两个互相交叉的数据集合中重叠部分以内的数据行联接起来。内联接使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中联接相匹配的数据行。
在表 A 和表 B 种使用内联接查询学生姓名、学校和职业:
select A.姓名 姓名A,A.学校 学校A,B.姓名 姓名B,B.职业 职业B
from A,B
where A.姓名=B.姓名
select A.姓名 姓名A,A.学校 学校A,B.姓名 姓名B,B.职业 职业B
from A INNER JOIN B ON A.姓名=B.姓名
外联接(outer join)是对内联接的扩充,除了将两个数据集合中重复部分以内的数据行联接起来之外,还可以根据要求返回左侧或右侧表中非匹配的数据或全部的数据。
外联接分为以下几种:
1.左外联接
在表 A 和表 B 中使用左外联接查询学生姓名、学校和职业:
select A.姓名 姓名A,A.学校 学校A,B.姓名 姓名B,B.职业 职业B
from A LEFT JOIN B ON A.姓名=B.姓名
2.右外联接
在 表 A 和表 B 中使用右外联接查询学生姓名、学校和职业:
select A.姓名 姓名A,A.学校 学校A,B.姓名 姓名B,B.职业 职业B
from A RIGHT JOIN B ON A.姓名=B.姓名
3.完整外联接
在 表 A 和表 B 中使用完整外联接查询学生姓名、学校和职业:
select A.姓名 姓名A,A.学校 学校A,B.姓名 姓名B,B.职业 职业B
from A FULL JOIN B ON A.姓名=B.姓名
交叉联接就是表之间没有任何关联条件,查询将返回左表与右表挨个联接的所有行,就是左表中的每行与右表中的所有行再一一组合
,相当于两个表"相乘"。