SQLserver学习day05 T-SQL数据操作(查询) 常用的函数

数据库查询

原理:将查询语句发向服务器,服务器将语句进行解析查找,然后将结果存在一张虚拟表中,发向客户端。

查询语法:SELECT 列名/* FROM 表名 [WHERE 限制条件] [ORDER BY(排序)]

1.查询表中所有信息

USE E_Market
GO
SELECT *FROM UserInfo--不加条件查询UserInfo表中的信息

2.查询指定列和指定行的信息

SELECT UserId,UserName,UserAddress FROM UserInfo WHERE Gender=1

3,给查询结果的列指定名字

有三种方法
(1) 使用AS指定名字

SELECT UserId AS 用户号,UserName AS 用户名字,UserAddress AS 用户地址 FROM UserInfo WHERE Gender=1

(2)使用=指定名字

SELECT 用户号码=UserId,用户name=UserName,用户住址=UserAddress FROM UserInfo WHERE Gender=1

(3)使用‘空格’指定名字

SELECT UserId 用户列,UserName 用户名,UserAddress 用户所在地 FROM UserInfo WHERE Gender=1

4.查询空值

SELECT UserId 用户列,UserName 用户名,UserAddress 用户所在地 FROM UserInfo WHERE UserAddress IS NULL

如果有数据被删除的话,那么IS NULL查询不到,这时候需要写 列名=‘ ’

SELECT UserId 用户列,UserName 用户名,UserAddress 用户所在地 FROM UserInfo WHERE UserAddress IS NULL OR UserAddress=''

NULL和‘ ’的区别,null是没写入过数据,还没有地址,‘ ’是写入数据后但删除了,是有地址的。

5.在查询中使用常量列

这里添加的常量列并不存在数据库中,而是存在虚拟表中。

SELECT UserId 用户列,UserName 用户名,UserAddress 用户所在地,'中国' AS 用户国籍 FROM UserInfo

6.查询的时候返回限定的行数

(1)返回限定的个数

--返回性别为0(女)的前五个人的信息
 SELECT TOP 5 UserId 用户列,UserName 用户名,UserAddress 用户所在地 FROM UserInfo WHERE Gender=0

(2)返回限定的百分比
返回的并不准确,只是一个大概的值,比如有7行信息,返回前20%,就是1.4,小数都进位,就是返回2行。

--返回性别为0(女)的前20%个人的信息
  SELECT TOP 20 PERCENT UserId 用户列,UserName 用户名,UserAddress 用户所在地 FROM UserInfo WHERE Gender=0

7.将查询的结果排序

升序是ASC 降序是DESC

--将UserInfo中按照UserId降序排列
SELECT UserId 用户列,UserName 用户名,UserAddress 用户所在地 FROM UserInfo ORDER BY UserId DESC

--先按照性别升序排列,再按照电话降序排列
 SELECT * FROM UserInfo ORDER BY Gender ASC,Phone DESC

<一>字符串函数

1.ASCII(返回字符表达式中最左侧的字符的 ASCII 代码值。)

2.CHAR(将 int ASCII 代码转换为字符。)

3.CHARINDEX ( expressionToFind ,expressionToSearch ,[ start_location ] )
(第一个是要搜索的字符串,第二个是总的字符串,第三个是从什么位置开始找(可以省略))。
(在一个表达式中搜索另一个表达式并返回其起始位置,没找到返回0)

SELECT CHARINDEX('LOVE','ILOVEYOU')
--结果返回2

4.CONCAT ( string_value1, string_value2 [, string_valueN ] )
(将几个字符串连接起来)

SELECT CONCAT('I','LOVE','YOU')
--结果是ILOVEYOU

5.LEFT和RIGHT(返回字符串中从左边(右边)开始指定个数的字符。)

 SELECT LEFT('ILOVEYOU',5)
 --结果是ILOVE

6.LEN(返回字符串长度)

7.REPLACE ( string_expression , string_pattern , string_replacement )
(1是要搜索的字符串,2是要被替换的,3是替换字符串)

 SELECT REPLACE('ILOVEYOU','LOVE','HATE') --结果是IHATEYOU

8.REVERSE(返回字符串的逆序)

9。STUFF ( character_expression , start , length , replaceWith_expression )
(1.要操作的字符串,2,开始位置,3,要删除的长度,4,替换的字符串)

SELECT STUFF('ILOVEYOU',2,4,'HATE')
--结果是IHATEYOU

10.SUBSTRING ( expression ,start , length )
(剪切字符串,1是字符串,2是起始位置,3是长度)

上面就是常用的字符串函数,可以查阅文档来学习其他字符串函数。

<二>日期和时间函数

1.GETDATE(),获得当前时间

2.DATEADD( datepart, number, date)(datepart是字母代替的日期的部分,MM代表月,YY代表年,DD代表天等等,number是要加的数值,date是日期)

SELECT DATEADD(YY,3,GETDATE())

3.DATEDIFF( datepart, startdate, enddate)(获得两个日期的差值)

--查看当前时间与2008-8-8年的差值
 SELECT DATEDIFF(YY,'2008-8-8',GETDATE()) 

4.DATENAME( datepart, date)(返回表示指定日期的指定日期部分的字符串。)

5.DATEPART( datepart, date)(返回表示指定日期的指定日期部分的整数。)

<三>数学函数

基本的乘方,随机数,绝对值,cos,sin等数学公式都在数学函数中,可以查阅帮助文档进行学习。

模糊查询

1.使用LIKE关键字进行模糊查询

语法:SELECT 列名或* FROM 表名 WHERE 列名 LIKE ‘%字符%’

--查询名字中带方的
 SELECT *FROM UserInfo WHERE UserName LIKE '%方%'

2.使用BETWEEN在某个范围内进行查询

语法:SELECT 列名或* FROM 表名 WHERE 列名 BETWEEN 小值 AND 大值

第一个值必须小于第二个值。其实相当于 BETWEEN 大于等于这个值 AND 小于等于这个值

 SELECT *FROM UserInfo WHERE UserId BETWEEN 1001 AND 1010

3.使用IN在列举值内进行查询

语法:SELECT 列名或* FROM 表名 WHERE 列名 IN(值1,值2,值3…….)

--查询来自北京,上海,郑州人的信息
 SELECT *FROM UserInfo WHERE UserAddress IN('北京','上海','郑州')

<四>聚合函数

聚合函数对一组值执行计算,并返回单个值。聚合函数经常与 SELECT 语句的 GROUP BY 子句一起使用。

COUNT 参数为*时,不忽略空值,所有行都被计数。
COUNT 参数为列名时,忽略空值

分组查询

如果我们想查询用户表中男女各多少个,由于聚合函数只能显示单行单列,所以只能用以下语句写。

SELECT COUNT(*) FROM UserInfo WHERE Gender=0 SELECT COUNT(*) FROM UserInfo WHERE Gender=1


当如果条件很多的时候,就会显得特别麻烦,所以提出了GROUP BY分组查询。

分组查询语法:

SELECT 聚合函数,分组的列 FROM 表名 [WHERE 条件] GROUP BY 分组的列
SELECT COUNT(*),Gender FROM UserInfo GROUP BY Gender

对分组之后的表进行条件查询,需要用到HAVING关键字,放在GROUP BY后面。

--按照性别和ID进行分组查询,分组后只查询ID大于1002的,并且按照降序
SELECT COUNT(*),Gender,UserId FROM UserInfo GROUP BY Gender,UserId HAVING UserId>1002 ORDER BY UserId DESC

内连接查询

多表连接查询:通过各个表之间共同列的关联性来查询数据,是关系数据库查询最主要的特征。

连接查询分为内连接和外连接。

内连接的特点

  • 两个表存在主外键关系
  • 参与查询的两个表的地位无主次之分

内连接实现的方式

(1)使用WHERE子句指定连接条件

四个表的关系图

两个表内连接查询

--订单信息表中的UserId引用用户信息表中的UserId,是主外键关系
SELECT UserInfo.UserId,UserInfo.UserName,OrderInfo.Amount FROM UserInfo,OrderInfo 
WHERE UserInfo.UserId=OrderInfo.UserId--必须指定两个表的哪两个值相等

三个表内连接查询

SELECT UserInfo.UserId,UserInfo.UserName,OrderInfo.Amount,ConmodityInfo.CommodityName 
FROM UserInfo,OrderInfo,ConmodityInfo 
WHERE UserInfo.UserId=OrderInfo.UserId AND OrderInfo.CommodityId=ConmodityInfo.CommodityId

使用INNER JOIN…….ON指定连接


SELECT UserInfo.UserName,UserInfo.Email,OrderInfo.Amount,OrderInfo.PayWay,ConmodityInfo.CommodityName --查询的列 FROM UserInfo --除了第一个表,后面 INNER JOIN 表名 ON 主外键关系 INNER JOIN OrderInfo ON UserInfo.UserId=OrderInfo.UserId INNER JOIN ConmodityInfo ON ConmodityInfo.CommodityId=OrderInfo.CommodityId

外连接查询

至少返回一个表中的所有记录,根据匹配条件有选择性地返回另一张表的记录。

外连接特点:

  • 参与外连接的表有主从之分

左外连接

在连接查询中,连接左端的表中的所有的行全部显示,并且能在右端的表中找到匹配的行,如果右端表中没能找到左端匹配的行,则对应NULL.

LEFT JOIN 左侧是主表

--查询商品类别的商品名字和库存量,商品类别表是主表
SELECT SortName,CommodityName, Amount FROM CommoditySort LEFT JOIN ConmodityInfo ON ConmodityInfo.SortId=CommoditySort.SortId

右外连接

和左外连接一样,连接右端表中的行全部显示,连接左端找到匹配的行,如果未能找到匹配的行,则用NULL代替。

--查询哪些商品没有订单
SELECT CommodityName,OrderId FROM OrderInfo RIGHT JOIN ConmodityInfo ON OrderInfo.CommodityId=ConmodityInfo.CommodityId

左右外连接可以相互转化。

上面的查询商品有没有订单的例子改成左外连接

SELECT CommodityName,OrderId FROM ConmodityInfo LEFT JOIN OrderInfo ON OrderInfo.CommodityId=ConmodityInfo.CommodityId

使用UNION合并查询

合并查询中两个表的列数和数据类型必须相同。
如果数据类型不同的话要进行数据类型转换。

SELECT UserName,Email FROM UserInfo UNION SELECT CONVERT(nvarchar(50),UId),CONVERT(varchar(50),UAddress) FROM UserAddress

合并查询时会自动舍弃重复的行,如果不想舍弃重复的行,需要UNION ALL就可以。

SELECT UserName,Email FROM UserInfo--第一个表 UNION SELECT CONVERT(nvarchar(50),UId),CONVERT(varchar(50),UAddress) FROM UserAddress--第二个表 UNION ALL SELECT UserName,Email FROM UserInfo--再合并一次第一个表

将会显示重复的行。

想将合并后的表存在新表中,INTO必须放在第一个表中。

SELECT UserName,Email INTO NEWTABLES--插入新表 FROM UserInfo UNION--合并 SELECT CONVERT(nvarchar(50),UId),CONVERT(varchar(50),UAddress) FROM UserAddress SELECT *FROM NEWTABLES--查询新表

如果向对合并后的表进行排序,ORDER BY必须放在最后一个表中

SELECT UserName,Email FROM UserInfo UNION SELECT CONVERT(nvarchar(50),UId),CONVERT(varchar(50),UAddress) FROM UserAddress ORDER BY UserName DESC--按UserName进行降序排列

子查询

子查询:在一个查询语句中包含了另外一个查询语句

简单子查询

特点

  • 子查询必须放在一对小括号内
  • 当比较运算符与子查询使用时,子查询要查询的列只能有一个
  • 子查询中不能存在ORDER BY 排序
--查询手机数码的商品信息
--1.先根据手机数码查出手机数码的编号
--2.再根据编号去查商品信息表中的信息
SELECT *FROM ConmodityInfo WHERE SortId= --这是是比较运算符,所以子查询只能查询一个列 ( SELECT SortId FROM CommoditySort WHERE SortName='手机数码' )
--查询购买华为手机的的姓名和住址
SELECT UserName,UserAddress FROM UserInfo WHERE UserId= ( SELECT UserId FROM OrderInfo WHERE CommodityId= ( SELECT CommodityId FROM ConmodityInfo WHERE CommodityName='华为手机' ) ) 

IN和NOT IN子查询

当比较运算符和子查询连接在一起时,只能返回一个列值,当返回多个列值时,就需要IN。

NOT IN是返回不包含子查询条件的列值。

----查询购买手机数码的人的信息
SELECT *FROM UserInfo WHERE UserId IN ( SELECT UserId FROM OrderInfo WHERE CommodityId IN ( SELECT CommodityId FROM ConmodityInfo WHERE SorTId= ( SELECT SortId FROM CommoditySort WHERE SortName='手机数码'--查询手机数码的类别号 )--查询属于手机数码的商品信息,因为很多手机都属于手机数码这个类别,所以 - --肯定有很多,而是算术运算符时只能返回一列信息,所以用IN ) )

--查询没有网购过的人的信息
SELECT * FROM UserInfo WHERE UserId NOT IN ( SELECT UserId FROM OrderInfo WHERE PayWay='网上银行' )

EXISTS查询

----对手机订单大于300的人打八折优惠
--判断是否存在手机数码订单超过300的
IF EXISTS(
SELECT * FROM OrderInfo WHERE CommodityId IN ( SELECT CommodityId FROM ConmodityInfo WHERE SortId= ( SELECT SortId FROM CommoditySort WHERE SortName='手机数码' ) )AND Amount>=300 ) --如果存在就打八折 BEGIN UPDATE OrderInfo SET PayMoney=PayMoney*0.8--把价格修改为八折 WHERE CommodityId IN--修改满足订单超过300这个条件的 ( SELECT CommodityId FROM OrderInfo WHERE CommodityId IN ( SELECT CommodityId FROM ConmodityInfo WHERE SortId= ( SELECT SortId FROM CommoditySort WHERE SortName='手机数码' ) )AND Amount>=300 ) END

ALL,ANY查询

创建两个表,table1中值为1,2,3,4,table2中为2.3

ALL查询是值父查询中的列的每一个值都大于或小于(看条件运算符)子查询中列的所有值

--一表中的值大于二表中的每一个值,只有4,结果为4
USE E_Market
GO
SELECT * FROM Table1 WHERE n>ALL(SELECT n FROM Table2)

ANY查询是指父查询中的只要有一个值满足条件即可

--一表中只要大于二表中的任何一个值即可
SELECT * FROM Table1 WHERE n>ANY(SELECT n FROM Table2)

=ANY:子查询的值和父查询中的值一样就返回


SELECT * FROM Table1 WHERE n=ANY(SELECT n FROM Table2)

<>ANY:只要父查询中的值有一个和子查询中的值不一样即可

SELECT * FROM Table1 WHERE n<>ANY(SELECT n FROM Table2)

子查询注意事项

任何允许使用表达式的地方都可以使用子查询。

你可能感兴趣的:(sql,数据库,server)