Microsoft SQL - 查询与更新
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Microsoft SQL - 查询与更新相关的知识,希望对你有一定的参考价值。
查询与更新(Query & Update)
转义引号
SQL语句中字符串只能使用单引号,如果需要转义,可用单引号转义单引号。
查询(Inquire)
以下公式中的c指代列名。
规则
1.查询语句的列名区分大小写。
2.查询语句的字符串只能使用单引号。
3.为每条语句加上分号表示一条语句结束,防止当一次执行多条语句时会抛错。
关键字:select
四种基本查询格式
直接查询
select * from stu
参数查询
将查询语句作为字符参数传递给exec执行函数
exec(\'select * from stu\')
declare @name varchar(10) , @en varchar(3)
select @name=\'姓名\',@en=\'英语\'
exec (\'select \'+@name+\',\'+@en+\' from 成绩单\')
命令查询
如果查询语句里使用了变量,则只能使用命令查询。
exec sp_executesql N\'select * from stu\'
指定列查询
select 职称,班级 from Teacher
form子句(来源)
所有查询
select * from Person.Address
部分查询
select AddressID,City from Person.Address //只查询该表的AddressID和City字段
列别名查询:列名 as
添加as该操作符可以为列名取一个别名,可在输出结果中查看,也可以为表定义别名。
select AddressID as 地址编号,City as 所在城市 from Person.Address
数学计算查询:列名+列名……
将每行中可计算的多个列的数据相加或相减,科使用+和-号将多个列连起来查询,计算结果可as到一个新的输出列中。
create table 成绩单
(
id int identity(1,1) not null constraint pk_id primary key,
name nvarchar(20) not null ,
en int,
math int
)
insert into 成绩单 values(\'sam\',90,80)
insert into 成绩单 values(\'john\',60,20)
insert into 成绩单 values(\'sam\',90,50)
select name as 姓名, en+math as 总分 from 成绩单
前n条记录查询:select top n[percent]
select top(1) name as 姓名, en+math as 总分 from 成绩单
//先查询每个人的名字和其英语和数学的分数总和,然后从这些结果里边只取出第一条记录
select top(50) percent * from 成绩单
//查询50%的行且是最靠前的行
列数据不重复查询:select distinct 列名
select distinct en from 成绩单
//每条记录中的en列如果有相等数据只取一条结果
完全限定表名查询
select Student.c from dbName.dbo.Student
Student:表名
c:列名
dbName:数据库名
dbo:数据库拥有者(默认,除非你更改了数据库拥有者的名字,否则直接写dbo即可)
为查询创建新表:into 新表 form 旧表
将查询结果装入一个新表,新表会存在与数据库中。
select id,name,math+en as score into 总成绩单 from 成绩单
join子句(联结)
多张表可能建立联系,比如学员表和成绩表,它们通过学员ID进行联系。join子句可以查询多张建立了联系的表,以on操作符所规定的条件进行过滤。
内联查询:inner join 另一张关联的表 on 条件(不匹配的记录不会输出)
内联查询就是将多张表联起来,以on操作符给出匹配条件,满足条件的记录会被查询。以下示例演示了如何查询多表联结的数据,查询两张表中有相同的FlimID的记录。
select Films.filmID,Films.FilmName,Films.YearMade,Actors.FirstName,Actors.LastName from Films inner join Actors
on Actors.filmID=Films.filmID
/*或*/
select a.filmID,a.FilmName,a.YearMade,b.FirstName,b.LastName from Films as a inner join Actors as b
on b.filmID=a.filmID
两张表能匹配的FilmID列的数据为1和2 所以输出结果为:(Actors的FilmID为5的记录在Films表中没有匹配,所以不会输出)
全联结查询:full join 另一张关联的表 on 条件(不匹配的记录以null填充)
将返回两张表的所有记录,不匹配的记录以null填充。
外联查询
左外联:left outer join 另一张关联的表 on 条件(不满足匹配时,保证左边记录可以显示,右边记录以null填充)
左侧的表如果与右侧的表中的某条记录不满足on的条件也会返回该条记录,左侧表中的记录会显示,右侧表的记录则以null填充。
select Films.filmID,FilmName,YearMade,FirstName,LastName from Actors left outer join Films
on Actors.filmID=Films.filmID
查询结果将会返回Actors表中的Humphrey所在行的记录,该记录不匹配FilmID,所以Film的FilmID和FilmName将会填充null。
右外联:right outer join 另一张关联的表 on 条件(不满足匹配时,保证右边记录可以显示,左边记录以null填充)
左侧的表如果与右侧的表中的某条记录不满足on的条件也会返回该条记录,右侧表中的记录会显示,左侧表的记录则以null填充。
多表联结查询
超过两张表的联结查询:
/*先join两张表,再继续join其它表*/
/*先join两张表,再继续join其它表*/ select * from UserManagers as a inner join Departments as b on a.DepartmentId=b.DepartmentId inner join TbRoses c on a.TbRoseId=c.TbRoseId
where子句(过滤)
在select返回的查询结果里使用where子句来筛选过滤出真正需要的数据。
select * from 成绩单
where en=90
where支持的操作符
= 、<>、!=、<、>、!<、!>、<=、>=、or、and、is null、not null、in(n1,n2……)、not in(n1,n2……)、like、not like、existis(子查询)[至少返回了一条记录则返回true]、x between y 介于某值到某值之间。
select * from 成绩单
where en>=60 and (id=1 or id=2)
//查询整个成绩单,在结果中筛选出英语成绩>=60并且学员编号为1或者2的记录
select * from Schedule
where year(StartDate) = \'2013\' and month(StartDate)=\'5\' and day(StartDate)=\'18\'
//匹配StartDate列的日期必须是2013-05-18
通配符过滤
通配符会拖慢整个搜索系统、效率最慢、最低。
百分号通配符%
表示任意字符,可以是0或者空字符串。
like \'%文本\'
like \'文本%\'
like \'%文本%\'
下划线通配符_
表示任意一个字符。
like \'_文本\'
like \'文本_\'
like \'_文本_\'
方括号通配符 [ ]
匹配出现在方括号内的任意一个字符,不管方括号内有几个字符,能匹配一个就行。
select * from 学员
where 名称 like \'[张李]%[三四]\'
//查询学员表,在结果中过滤出名称一列中以张或者李开头以三或者四结尾的记录
方括号否定通配符 [^ ]
^是不以的意思。
select * from 学员
where 名称 like \'[^张李]%[^三四]\'
//查询学员表,在结果中过滤出名称一列中名称不以张或者李开头且不以三或者四结尾的记录
order by子句(排序)
该子句必须放在所有select子句的末尾。
升序查询:order by 列名 asc 此为默认,可不写asc
降序查询:order by 列名 desc
select name,math from 成绩单
order by en desc;
//这里并没有查询英语成绩,但还是可以按en进行排序
多列排序
列名之间逗号隔开,采取就近原则(离order by最近的列),如果当前排序出现数据相同的情况,会按后一个列的数据为准进行排序。
升降混排
select * from 成绩单
order by en desc,math
//按英语成绩降序排序,遇到英语成绩相同的列 就按数学成绩升序排序
字母排序
A<Z,无法按小写排序。
group by子句
普通分组:group by 列名
对表数据进行分组,纵向的一列中相同的数据会被归纳为一组,可以把分为一组的数据想象为一张表 里边存储了一个列 这个列有N行相同纪录的数据
select 英语 from 成绩
group by 英语
聚合函数分组
group by 可以组合聚合函数来实现分组计算,聚合函数的计算行为是基于分组后的列而非分组前。
select 英语,count(*) as 记录条数 from 成绩
group by 英语
过滤分组
having子句来为分组后数据过滤,类似where子句过滤。区别在于where过滤的是整张表的查询结果,而having只过滤已被分组的数据 。该子句使用的操作符与where一样。
//查询顾客的订单有2个以上的记录 :
select 顾客id,count(*) as 记录条数 from orders as 顾客订单
group by 顾客id
having count(*) >=2
//查询顾客订单表的所有记录,然后在结果里以顾客id进行分组,并临时生成一个新列统计记录条数,使用having过滤出顾客的订单有2个以上的记录
分组规则
1.靠select最近的依次为:where>group by > order by
2.select中如果出现表达式那么group by也必须出现该表达式。
3.select中查询的列必须是group by的列,group by的列有几个,select的列就得有几个,多一个都不行。
单向子查询
子查询就是在一个查询语句中使用了另一个嵌套在括号中的查询语句,嵌套子查询只朝一个方向进行,要么返回一个用于外部需要的查询的结果(单个结果值),要么返回一个值的列表(多个值),如果需要返回一个值列表,则必须在外部查询中使用in运算符。
子查询单值返回:
create table 产品
(
产品ID int not null identity(10000,1) primary key,
产品名称 nvarchar(20) not null
)
create table 订单
(
订单ID int not null identity primary key,
订单日期 smalldatetime not null ,
产品ID int not null foreign key references 产品(产品ID)
)
insert into 产品(产品名称)values(\'奇鸟行状录\')
insert into 产品(产品名称)values(\'爵士乐群英谱\')
insert into 产品(产品名称)values(\'荒凉天使\')
insert into 产品(产品名称)values(\'吴哥的微笑\')
insert into 订单(订单日期,产品ID)values(\'1990-12-12\',\'10000\')
insert into 订单(订单日期,产品ID)values(\'1990-11-11\',\'10001\')
insert into 订单(订单日期,产品ID)values(\'1990-12-11\',\'10002\')
insert into 订单(订单日期,产品ID)values(\'1990-12-10\',\'10003\')
现在要从内联查询的结果中找出日期最早的订单
select a.订单日期,a.产品ID,b.产品名称 from 订单 as a inner join 产品 as b
on a.产品ID=b.产品ID
where a.订单日期=(select min(订单日期) from 订单)
/*将两张表建立内联查询,获取两张表中产品ID能匹配的记录*/
/*再从结果里过滤出日期最早的订单*/
子查询多值返回:
select a.订单日期,a.产品ID,b.产品名称 from 订单 as a inner join 产品 as b
on a.产品ID=b.产品ID
where 订单日期 in (select 订单日期 from 订单 where 订单日期 >=\'1990-12-10\' )
/*where 订单日期 in (select 订单日期 from 订单 where 订单日期 between \'1990-12-10\' and \'1990-12-12\' )*/
子查询操作符
关键字:> any (select)
>any子查询中的最小值,select是子查询语句,子查询语句必须返回一个值列表。
select a.订单日期,a.产品ID,b.产品名称 from 订单 as a inner join 产品 as b
on a.产品ID=b.产品ID
where 订单日期 > any (select 订单日期 from 订单 where 订单日期 between \'1990-12-10\' and \'1990-12-12\')
/*这个any子查询就是以下逻辑,但不能直接像下面那样去写,any括号里必须是能返回值列表的查询语句*/
where 订单日期 > any (\'1990-12-10\',\'1990-12-11\',\'1990-12-12\')
关键字:< any ( 子查询 )
小于any中的最大值。
关键字:= any 以上是关于Microsoft SQL - 查询与更新的主要内容,如果未能解决你的问题,请参考以下文章 Microsoft SQL Server查询分析器不能与本机连接? sql [SQL查询片段]用于在命令行或通过R和其他工具使用SQL的快速代码段#tags:sql,R,text processing,命令li 2013, '在查询期间丢失与 MySQL 服务器的连接 - Pymysql Microsoft sql server management Studio