一. 前言

该篇文章基于之前   https://www.cnblogs.com/yaopengfei/p/7182230.html  的基础上进行补充修改。

1. 简介

就查询而言,可以简单的分为:单表查询 和 多表查询。

单表查询包括:简单查询、过滤查询、结果排序、分页查询、聚集函数。

多表查询包括:笛卡尔积、外键约束、内连接查询、外链接查询、自连接查询。

2. 数据准备

(1). 用到的表:

产品表(product)。包括:主键id、产品名称(productName)、分类编号(dir_id)、零售价(salePrice)、供应商(supplier)、品牌(brand)、折扣(cutoff)、成本价(costPrice)。

产品分类编号表( productdir)。 包括:主键id、编号名称( dirName)、父id( parent_id) 。

产品库存表( productstock)。包括:主键id、产品id( product_id )、库存数量( storeNum)、上次进库时间(lastIncomeDate)、上次出库时间( lastOutcomeDate)、预警数量(warningNum)。

(2). 对应的字段类型,如下图:

(3). 用到的SQL语句:

product表

CREATE TABLE`product` (

`id`bigint(11) NOT NULLAUTO_INCREMENT,

`productName`varchar(50) DEFAULT NULL,

`dir_id`bigint(11) DEFAULT NULL,

`salePrice`double(10,2) DEFAULT NULL,

`supplier`varchar(50) DEFAULT NULL,

`brand`varchar(50) DEFAULT NULL,

`cutoff`double(2,2) DEFAULT NULL,

`costPrice`double(10,2) DEFAULT NULL,PRIMARY KEY(`id`)

) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;--------------------------------Records of product------------------------------

INSERT INTO `product` VALUES ('1', '罗技M90', '3', '90.00', '罗技', '罗技', '0.50', '35.00');INSERT INTO `product` VALUES ('2', '罗技M100', '3', '49.00', '罗技', '罗技', '0.90', '33.00');INSERT INTO `product` VALUES ('3', '罗技M115', '3', '99.00', '罗技', '罗技', '0.60', '38.00');INSERT INTO `product` VALUES ('4', '罗技M125', '3', '80.00', '罗技', '罗技', '0.90', '39.00');INSERT INTO `product` VALUES ('5', '罗技木星轨迹球', '3', '182.00', '罗技', '罗技', '0.80', '80.00');INSERT INTO `product` VALUES ('6', '罗技火星轨迹球', '3', '349.00', '罗技', '罗技', '0.87', '290.00');INSERT INTO `product` VALUES ('7', '罗技G9X', '3', '680.00', '罗技', '罗技', '0.70', '470.00');INSERT INTO `product` VALUES ('8', '罗技M215', '2', '89.00', '罗技', '罗技', '0.79', '30.00');INSERT INTO `product` VALUES ('9', '罗技M305', '2', '119.00', '罗技', '罗技', '0.82', '48.00');INSERT INTO `product` VALUES ('10', '罗技M310', '2', '135.00', '罗技', '罗技', '0.92', '69.80');INSERT INTO `product` VALUES ('11', '罗技M505', '2', '148.00', '罗技', '罗技', '0.92', '72.00');INSERT INTO `product` VALUES ('12', '罗技M555', '2', '275.00', '罗技', '罗技', '0.88', '140.00');INSERT INTO `product` VALUES ('13', '罗技M905', '2', '458.00', '罗技', '罗技', '0.88', '270.00');INSERT INTO `product` VALUES ('14', '罗技MX1100', '2', '551.00', '罗技', '罗技', '0.76', '300.00');INSERT INTO `product` VALUES ('15', '罗技M950', '2', '678.00', '罗技', '罗技', '0.78', '320.00');INSERT INTO `product` VALUES ('16', '罗技MX Air', '2', '1299.00', '罗技', '罗技', '0.72', '400.00');INSERT INTO `product` VALUES ('17', '罗技G1', '4', '155.00', '罗技', '罗技', '0.80', '49.00');INSERT INTO `product` VALUES ('18', '罗技G3', '4', '229.00', '罗技', '罗技', '0.77', '96.00');INSERT INTO `product` VALUES ('19', '罗技G500', '4', '399.00', '罗技', '罗技', '0.88', '130.00');INSERT INTO `product` VALUES ('20', '罗技G700', '4', '699.00', '罗技', '罗技', '0.79', '278.00');

View Code

productdir表

CREATE TABLE`productdir` (

`id`bigint(11) NOT NULLauto_increment,

`dirName`varchar(30) default NULL,

`parent_id`bigint(11) default NULL,PRIMARY KEY(`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;--------------------------------Records------------------------------

INSERT INTO `productdir` VALUES ('1', '鼠标', null);INSERT INTO `productdir` VALUES ('2', '无线鼠标', '1');INSERT INTO `productdir` VALUES ('3', '有线鼠标', '1');INSERT INTO `productdir` VALUES ('4', '游戏鼠标', '1');

View Code

productstock表

CREATE TABLE`productstock` (

`id`bigint(11) NOT NULLauto_increment,

`product_id`bigint(11) default NULL,

`storeNum`int(10) default NULL,

`lastIncomeDate`datetime default NULL,

`lastOutcomeDate`datetime default NULL,

`warningNum`int(10) default NULL,PRIMARY KEY(`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;--------------------------------Records------------------------------

INSERT INTO `productstock` VALUES ('1', '1', '182', '2015-03-12 20:33:00', '2015-03-12 20:33:04', '20');INSERT INTO `productstock` VALUES ('2', '2', '27', '2015-03-02 20:33:28', '2015-03-09 20:33:40', '20');INSERT INTO `productstock` VALUES ('3', '3', '89', '2015-02-28 20:34:13', '2015-03-12 20:34:19', '20');INSERT INTO `productstock` VALUES ('4', '5', '19', '2015-03-01 20:34:43', '2015-03-12 20:34:48', '20');INSERT INTO `productstock` VALUES ('5', '6', '3', '2015-02-01 20:35:12', '2015-03-02 20:35:16', '5');INSERT INTO `productstock` VALUES ('6', '7', '2', '2015-02-02 20:35:59', '2015-02-27 20:36:05', '3');INSERT INTO `productstock` VALUES ('7', '8', '120', '2015-03-12 20:36:31', '2015-03-12 20:36:33', '20');INSERT INTO `productstock` VALUES ('8', '9', '58', '2015-03-02 20:36:50', '2015-03-12 20:36:53', '20');INSERT INTO `productstock` VALUES ('9', '11', '28', '2015-03-02 20:37:12', '2015-03-12 20:37:15', '20');INSERT INTO `productstock` VALUES ('10', '12', '8', '2015-03-02 20:37:35', '2015-03-09 20:37:38', '5');INSERT INTO `productstock` VALUES ('11', '13', '3', '2015-03-02 20:37:58', '2015-03-12 20:38:01', '5');INSERT INTO `productstock` VALUES ('12', '14', '6', '2015-03-02 20:38:20', '2015-03-07 20:38:23', '5');INSERT INTO `productstock` VALUES ('13', '15', '2', '2015-02-02 20:38:38', '2015-02-24 20:38:44', '5');INSERT INTO `productstock` VALUES ('14', '16', '3', '2015-02-02 20:39:05', '2015-02-06 20:39:09', '3');INSERT INTO `productstock` VALUES ('15', '17', '49', '2015-03-02 20:39:36', '2015-03-12 20:39:40', '20');INSERT INTO `productstock` VALUES ('16', '18', '14', '2015-03-02 20:39:57', '2015-03-09 20:40:01', '10');INSERT INTO `productstock` VALUES ('17', '20', '7', '2015-03-02 20:40:22', '2015-03-03 20:40:25', '5');

View Code

3. 经典SQL的执行顺序

二. 单表查询

1. 简单查询

a.  消除结果中的重复数据,用 DISTINCT 关键字。

b.  数学逻辑运算符(+ - * / ),运算符的优先级为:

(1). 乘除高于加减。

(2). 同级运算从左到右。

(3). 括号的优先级最高。

c.  设置列名的别名。

(1). 改变列的标题头,用as 关键字,可以省略。

(2). 用于表示计算结果的含义。

(3). 如果别名中有特殊字符,或者轻质大小写敏感,或有空格是,都需要加双引号。

#1.需求:查询所有货品信息select * fromproduct

#2.查询所有货品的id,productName,salePriceselect id,productName,salePrice fromproduct

#3需求:查询商品的分类编号。SELECT DISTINCT dir_id FROM product

#需求:查询所有货品的id,名称和批发价(批发价=卖价*折扣)SELECT id,productName,salePrice*cutoff FROMproduct

#需求:查询所有货品的id,名称,和各进50个的成本价(成本=costPirce)SELECT id,productName,costPrice*50 FROMproduct

#需求:查询所有货品的id,名称,各进50个,并且每个运费1元的成本SELECT id,productName,(costPrice+1)*50 FROM product

SELECT id,productName,(costPrice+1)*50 as pf FROMproductSELECT id,productName,(costPrice+1)*50 pf FROMproductSELECT id,productName,(costPrice+1)*50 "p f" FROM product

2. 过滤查询

a. SQL语句的执行顺序: FROM → WHERE → SELECT → ORDER BY。

b. 逻辑运算符:

(1). AND (&&) : 组合条件都为true,返回true。

(2). OR ( || ) : 组合条件之一为true, 就返回true。

(3). NOT ( ! ) : 组合条件都为false,返回true。

需求: 选择id,货品名称,批发价在300-400之间的货品SELECT id productName,salePrice FROM product WHERE salePrice >=300 AND salePrice<=400需求: 选择id,货品名称,分类编号为2,4的所有货品SELECT id productName,salePrice FROM product WHERE dir_id=3 OR dir_id<=4需求: 选择id,货品名词,分类编号不为2的所有商品SELECT id productName,salePrice FROM product WHERE dir_id!=2

SELECT id productName,salePrice FROM product WHERE NOT dir_id=2需求: 选择id,货品名称,分类编号的货品零售价大于等于250或者是成本大于等于200SELECT id,productName,dir_id,salePrice,costPrice from product WHERE salePrice >=250 or costPrice>=200

c. 比较运算符:

(1). 等于: =

(2). 大于: >

(3). 大于或等于: >=

(4). 小于:<

(5). 小于或等于:<=

(6). 不等于: !=    或 <>

注意:运算符的优先级由低到高:所有比较运算符 → NOT → AND → OR → 括号。

# 需求: 查询货品零售价为119的所有货品信息.SELECT * FROM product WHERE salePrice=119#需求: 查询货品名为罗技G9X的所有货品信息.SELECT * FROM product WHERE productName='罗技G9X'

SELECT * FROM product WHERE productName='罗技g9x'

SELECT * FROM product WHERE BINARY productName='罗技g9x'#二进制区分大小写

#需求: 查询货品名 不为 罗技G9X的所有货品信息.SELECT * FROM product WHERE productName!='罗技G9X'

SELECT * FROM product WHERE productName<>'罗技G9X'需求: 查询分类编号不等于2的货品信息SELECT * FROM product WHERE dir_id!=2需求: 查询货品名称,零售价小于等于200的货品SELECT productName FROM product WHERE salePrice<=200需求: 查询id,货品名称,批发价大于350的货品SELECT id,productName,salePrice *cutoff FROM product WHERE salePrice *cutoff >350思考:使用where后面使用别名不行,总结select和where的执行顺序(思考下面两个都不好用的原因,

第二个是因为别名只能放在列名的后面)SELECT id,productName,salePrice *cutoff pf FROM product WHERE pf >350

SELECT id,productName, pf FROM product WHERE salePrice *cutoff pf >350

SELECT id,productName FROM product WHERE (NOT productName LIKE '%M%' AND salePrice > 100) OR (dir_id = 2)

d. 范围查询:BETWEEN AND 表示某一值域范围的记录。

格式: SELECT * FROM 表名 WHERE 列名 BETWEEN minvalue ANDmaxvalue;   (两边都为闭区间)。

需求: 选择id,货品名称,批发价在300-400之间的货品SELECT id,productName,salePrice FROM product WHERE salePrice BETWEEN 300 AND 400需求: 选择id,货品名称,批发价不在300-400之间的货品SELECT id,productName,salePrice FROM product WHERE NOT salePrice BETWEEN 300 AND 400

e. 集合查询:使用IN运算符,判断列的值是否在指定的集合中。

格式: WHERE 列名 IN ( 值1, 值2,....) 。

需求:选择id,货品名称,分类编号为2,4的所有货品SELECT id productName,salePrice FROM product WHERE dir_id=2 OR dir_id=4

SELECT id productName,salePrice FROM product WHERE dir_id IN(2,4)

需求:选择id,货品名称,分类编号不为2,4的所有货品

SELECT id productName,salePrice FROM product WHERE NOT dir_id IN(2,4)

f. 空值判断:IS NULL,判断列的值是否为空。

格式:WHERE 列名 IS NULL。

--需求:查询商品名为NULL的所有商品信息。

SELECT * FROM product WHERE productName IS NULL

g. 模糊查询:使用LIKE 运算符执行通配查询。

(1). %: 表示零或多个字符。

(2). _ : 表示一个字符。

需求: 查询id,货品名称,货品名称匹配'%罗技M9_'

SELECT id, productName FROM product WHERE productName LIKE '%罗技M9_'需求: 查询id,货品名称,分类编号,零售价大于等于200并且货品名称匹配'%罗技M1__'

SELECT id,productName,dir_id FROM product WHERE productName LIKE '%罗技M9__' AND salePrice >=200

3. 结果排序

使用ORDER BY 子句进行排序,ASC: 升序 (默认,可省),DESC:降序;ORDER BY 子句出现在SELECT语句最后。

格式: SELECT *

FROM table_name

WHERE 条件

ORDER BY 列名1 [ASC/DESC] , 列名2 [ASC/DESC]  .... 。

注意: 不能对使用了引号的别名进行排序。

#按照某一列来排序:

#需求:选择id,货品名称,分类编号,零售价并且按零售价降序排序SELECT id,productName,dir_id,salePrice from product ORDER BY salePrice DESC#按多列排序:

#需求: 选择id,货品名称,分类编号,零售价先按分类编号排序,再按零售价排序SELECT id,productName,dir_id,salePrice from product ORDER BY dir_id ASC,salePrice DESC#列的别名排序:

#需求:查询M系列并按照批发价排序(加上别名)SELECT * ,salePrice * cutoff FROM product WHERE productName LIKE '%M%' ORDER BY salePrice *cutoffSELECT * ,salePrice * cutoff pf FROM product WHERE productName LIKE '%M%' ORDER BYpf

#需求:查询分类为2并按照批发价排序(加上别名)SELECT * ,salePrice * cutoff "pf" FROM product WHERE dir_id=2 ORDER BY "pf"

4. 分页

(1). 真分页(物理分页、数据库分页):每次分页的时候,都从数据库中截取指定条数的数据。优点:不会内存溢出。缺点:复杂,翻页比较慢。

假分页(逻辑分页、内存分页):一次性把数据全部查出来,存在内存里,翻页的时候,从内存中截取指定条数即可。优点:简单,翻页快。缺点:若数据过多,可能内存溢出。

(2). MySQL中分页的写法:

格式1:LIMIT beginIndex, pageSize ;

其中,beginIndex,表示从哪一个索引位置开始截取数据(索引是从0开始),   pageSize,表示每页显示最多的条数

分页语句:SELECT * FROM 表名 LIMIT (currentPage-1)*pageSize,pageSize .

currentPage为当前页数,通常是前端传递过来的。

--分页 (获取的是 第11,12,13 条数据)

SELECT * FROM product LIMIT 10,3

格式2:LIMIT N ;   代表取前N条数据。 (等价于: LIMIT 0,N )

--获取的是前10条数据SELECT * FROM product LIMIT 10

格式3:LIMIT M,-1 ;   代表获取第 M+1条 到最后的数据( MySQL5.7中已经不支持这种写法了)

--获取第11条 到 最后的数据

SELECT * FROM product LIMIT 10,-1

格式4:LIMIT M OFFSET N ;   代表跨过N条数据,取M条数据

--获取的是第 3,4 ,5条数据

select * from T_WxLoginUser LIMIT 2,3;--获取的也是第 3,4 ,5条数据 (和上面的语句效果等价)

select * from T_WxLoginUser LIMIT 3 OFFSET 2;

(3). SQLServer分页:

方案一:利用ROW_NUMBER() over() 和between  and,进行分页。ROW_NUMBER() over() 表示把该表按照某个字段进行排序,然后新生成一列,从1到n,如下图:

over里的排序要晚于外层 where,group by,order by

会按照over里面的排序,新增一列(1----n),比如 newRow, 然后基于这一列,使用between and 进行区间获取

可以将出来的数据进行排列1-----n,即多了一列

select *, ROW_NUMBER() over(order by userAge desc) as newRow from UserInfor

演变过程:

select *, ROW_NUMBER() over(order by userAge desc) as newRow fromUserInforselect * from(select *, ROW_NUMBER() over(order by userAge desc) as newRow from UserInfor) astselect * from(select *, ROW_NUMBER() over(order by userAge desc) as newRow from UserInfor) astwhere t.newRow between 1 and 2

方案2:利用offset-fetch (SQLServer2012后开始支持),分页实现的思路:

--在分页实现中,使用Order By子句,按照指定的columns对结果集进行排序;

--使用offset子句跳过前N条:offset (@PageIndex-1)*@RowsPerPage rows;

--使用fetch子句取N条:fetch next @RowsPerPage rows only;

--跨过3行取剩下的

select * from UserInfor order by userAge descoffset3rows--跨过3行取剩下2行

select * from UserInfor order by userAge descoffset3rowsfetch next 2 rows only

封装成存储过程:(这里基于方案一、方案二各一种,然后基于方案一写了一个万能的分页)

--基于"方案一"的存储过程分页

if (exists (select * from sys.objects where name = 'FenYe1'))drop procFenYe1go

create procFenYe1(@pageSize int=3, --输入参数:每页的条数,默认值为2

@pageIndex int=1, --输入参数:当前页数,默认值为1

@totalCount int output, --输出参数:总条数

@pageCount int output --输出参数:总页数

)as

select * from(select *, ROW_NUMBER() over(order by userAge desc) as newRow from UserInfor) astwhere t.newRow between ((@pageIndex-1)*@pageSize)+1 and (@pageSize*@pageIndex);select @totalCount=COUNT(*) fromUserInfor;set @pageCount=CEILING(@totalCount * 1.0 /@pageSize);--执行该分页的存储过程

declare @myTotalCount int, --声明变量用来接收存储过程中的输出参数

@myPageCount int --声明变量用来接收存储过程中的输出参数

exec FenYe1 2,1,@myTotalCount output,@myPageCount output; --每页2条,求第1页的数据

select @myTotalCount as '总条数',@myPageCount as '总页数';--基于"方案二"的存储过程分页

if (exists (select * from sys.objects where name = 'FenYe2'))drop procFenYe2go

create procFenYe2(@pageSize int=3, --输入参数:每页的条数,默认值为2

@pageIndex int=1, --输入参数:当前页数,默认值为1

@totalCount int output, --输出参数:总条数

@pageCount int output --输出参数:总页数

)as

select * from UserInfor order by userAge descoffset (@pageIndex-1)*@pageSize rows fetch next @pageSize rows only;select @totalCount=COUNT(*) fromUserInfor;set @pageCount=CEILING(@totalCount * 1.0 /@pageSize);--执行该分页的存储过程

declare @myTotalCount int, --声明变量用来接收存储过程中的输出参数

@myPageCount int --声明变量用来接收存储过程中的输出参数

exec FenYe2 4,2,@myTotalCount output,@myPageCount output; --每页4条,求第2页的数据

select @myTotalCount as '总条数',@myPageCount as '总页数';--基于"方案一"创建一个万能表的分页

if (exists (select * from sys.objects where name = 'WangNengFenYe'))drop procWangNengFenYego

create procWangNengFenYe(@TableName varchar(50), --表名

@ReFieldsStr varchar(200) = '*', --字段名(全部字段为*)

@OrderString varchar(200), --排序字段(必须!支持多字段不用加order by)

@WhereString varchar(500) =N'', --条件语句(不用加where)

@PageSize int, --每页多少条记录

@PageIndex int = 1 , --指定当前为第几页

@TotalRecord int output --返回总记录数

)as

begin

--处理开始点和结束点

Declare @StartRecord int;Declare @EndRecord int;Declare @TotalCountSql nvarchar(500);Declare @SqlString nvarchar(2000);set @StartRecord = (@PageIndex-1)*@PageSize + 1

set @EndRecord = @StartRecord + @PageSize - 1

SET @TotalCountSql= N'select @TotalRecord = count(*) from' + @TableName;--总记录数语句

SET @SqlString = N'(select row_number() over (order by'+ @OrderString +') as rowId,'+@ReFieldsStr+'from'+ @TableName;--查询语句

-- IF (@WhereString! = '' or @WhereString!=null)BEGIN

SET @TotalCountSql=@TotalCountSql + 'where'+ @WhereString;SET @SqlString =@SqlString+ 'where'+ @WhereString;END

--第一次执行得到

--IF(@TotalRecord is null)

--BEGIN

EXEC sp_executesql @totalCountSql,N'@TotalRecord int out',@TotalRecord output;--返回总记录数

--END

----执行主语句

set @SqlString ='select * from' + @SqlString + ') as t where rowId between' + ltrim(str(@StartRecord)) + 'and' + ltrim(str(@EndRecord));Exec(@SqlString)END

--执行--对UserInfor表进行分页,根据userAge排序,每页4条,求第2页的数据

declare @totalCount int

exec WangNengFenYe 'UserInfor','*','userAge desc','',4,2,@totalCountoutput;select @totalCount as '总条数';--总记录数。

View Code

5. 聚集函数

(1). COUNT : 统计结果的记录数。

(2). MAX : 统计计算最大值。

(3). MIN : 统计最小值。

(4). SUM: 统计计算求和。

(5). AVG: 统计计算平均值。

需求:查询所有商品平均零售价SELECT AVG(salePrice) FROMproduct

需求:查询商品总记录数(注意在Java中必须使用long接收)SELECT COUNT(id) FROMproduct

需求:查询分类为2的商品总数SELECT COUNT(id) FROM product WHERE dir_id=2需求:查询商品的最小零售价,最高零售价,以及所有商品零售价总和SELECT MIN(salePrice) 最小零售价,MAX(salePrice) 最高零售价,SUM(salePrice) 商品零售价总和 FROM product

三. 多表查询

1. 笛卡尔积

多表查询会产生笛卡尔积。 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)},实际运行环境下,应避免使用全笛卡尔集。

解决笛卡尔积最有效的方法:等值连接(是内连接的一种)。

--需求:查询所有的货品信息+对应的货品分类信息

SELECT productName,dirName FROM product,productdir WHERE dir_id = productdir.id

2. 外键约束

(1). 主键约束(PRIMARY KEY): 约束在当前表中,指定列的值非空且唯一.

(2). 外键约束(FOREIGN KEY): A表中的外键列. A表中的外键列的值必须参照于B表中的某一列(B表主键).

注意:在MySQL中,InnoDB支持事务和外键.修改表的存储引擎为InnDB。格式:ALTER TABLE 表名 ENGINE='InnoDB'。

3. 说明

(1) 主表:数据可以独立存在,就是被参考的表。 productdir

(2). 从表:表中的数据,必须参照于主表的数据。product

注意:在删除表的时候,先删除从表,再删除主表。

3. 多表查询详解

多表查询包括三类:内连接查询(隐式内连接和显示内连接)、外连接查询 (左外链接、右外链接、全链接 )、自连接查询,各自的关系如下图:

经典代码分享:

/*1*/

SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key;/*2*/

SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key;/*3*/

SELECT FROM TableA A INNER JOIN TableB B ON A.Key = B.Key;/*4*/

SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key WHEREB.Key IS NULL;/*5*/

SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key WHEREA.Key IS NULL;/*6*/

SELECT FROM TableA A FULL OUTER JOIN TableB B ON A.Key = B.Key;/*MySQL不支持FULL OUTER JOIN这种语法 可以改成 1+2*/

SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key

UNION

SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key;/*7*/

SELECT FROM TableA A FULL OUTER JOIN TableB B ON A.Key = B.Key

WHERE A.Key IS NULL OR B.Key IS NULL;/*MySQL不支持FULL OUTER JOIN这种语法 可以改成 4+5*/

SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key WHEREB.Key IS NULL;UNION

SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key WHEREA.Key IS NULL;

View Code

注:在MySQL中,join、inner join、cross join含义相同,都是用于等值连接的,另外MySQL中没有 full outer join,可以通过left join + right join +union来实现相应需求。

(1). 内连接

内连接查询出来的结果是多表交叉共有的,分为:隐式内连接和显示内连接。 还有一种划分方式,内连接分为:等值连接和非等值连接。

PS:不管是隐式内连接还是显示内连接, 当写法是  A.列 = B.列 的时候,就是等值连接;但如果写成  A.列!=B.列 就是非等值连接,所以说等值连接是内连接的子级。【如有出入,欢迎探讨】

A. 隐式内连接 (关键字 =)

B. 显示内连接 (关键字  inner join on,inner可以省略,推荐写法)

PS 在做等值连接的时候,若A表中的和B表中的列相同,可以缩写为:(MySQL特有)

需求:查询所有商品的名称和分类名称:

隐式内连接:SELECT p.productName,pd.dirName FROM product p,productdir pd WHERE p.dir_id =pd.id

显示内连接:SELECT p.productName,pd.dirName FROM product p INNER JOIN productdir pd ON p.dir_id =pd.id

显示内连接:SELECT p.productName,pd.dirName FROM product p JOIN productdir pd ON p.dir_id =pd.id

需求: 查询零售价大于200的无线鼠标SELECT * FROM product p,productdir pd WHERE p.dir_id = pd.id AND p.salePrice >200 Andpd.dirName='无线鼠标'

SELECT * FROM product p JOIN productdir pd on p.dir_id = pd.id WHERE p.salePrice >200 Andpd.dirName='无线鼠标'需求: 查询每个货品对应的分类以及对应的库存SELECTp.productName,pd.dirName,ps.storeNumFROMproduct p,productdir pd,productstock psWHERE p.dir_id = pd.id AND p.id =ps.product_idSELECTp.productName,pd.dirName,ps.storeNumFROMproduct pJOIN productdir pd on p.dir_id =pd.idJOIN productstock ps on p.id =ps.product_id

需求: 如果库存货品都销售完成,按照利润从高到低查询货品名称,零售价,货品分类(三张表).select *, (p.salePrice - p.costPrice) *ps.storeNum lirunFROMproduct p,productdir pd,productstock psWHERE p.dir_id = pd.id AND p.id =ps.product_idORDER BY lirun DESC

select *, (p.salePrice - p.costPrice) *ps.storeNum lirunFROMproduct pJOIN productdir pd on p.dir_id =pd.idJOIN productstock ps on p.id =ps.product_idORDER BY lirun DESC

(2). 外连接查询

左外连接:查询出JOIN左边表的全部数据,JOIN右边的表不匹配的数据用NULL来填充,关键字:left join

右外连接:查询出JOIN右边表的全部数据,JOIN左边的表不匹配的数据用NULL来填充,关键字:right join

全连接: (左连接 - 内连接) +内连接 + (右连接 - 内连接) = 左连接+右连接-内连接  关键字:full join

PS: A LEFT JOIN B  等价于  B RIGHT JOIN A

注意:无论是左外连接还是右外连接,都要注意 1对多 的情况,左外链接的数据数量取决于左表,右外链接的数据数量取决于右表。

--外链接

# 查询所有商品的名称和分类名称

左连接:SELECT * FROM product p LEFT JOIN productdir pd ON p.dir_id =pd.id--等价于

SELECT * FROM productdir pd RIGHT JOIN product p ON p.dir_id =pd.id

右连接:SELECT * FROM product p RIGHT JOIN productdir pd ON p.dir_id = pd.id

(3). 自连接查询:把一张表看成两张表来做查询

补充一个例子:

S表(学生表):sno(学号)、sname(学生姓名)、sage、ssex。

求学号比 WANG 同学大,而年龄比他小的学生姓名。

--写法1

select sname from S wheresno> (select sno from S where sname = 'WANG')andsage< (select sage from S where sname ='WANG');--写法2 (自连接)

select S2.sname from S as S1, S asS2where S1.sno=S2.snoand S1.sname='WANG' and S2.sno>S1.sno and S2.sage < S1.sage;

四. 其它

1. group by 分组

SQL中的group by分组与linq、lambda完全不同,select中查询的字段必须是group by语句的后面字段,作为分组的依据;如果要使用其他字段,其他字段必须被包含在聚合函数中。常见的聚合函数有:count、sum、avg、min、max。

group by 后面通常会加having,表示对分组后的数据进行限制。

案例1

--根据用户性别分类,统计不同性别年龄最大值,年龄总和,用户数量。

select userSex,MAX(userAge) as MaxAge,SUM(userAge) as TotalAges,count(*) asNumfromSys_UserInforgroup by userSex

案例2

查询只选修了一门课程的学员姓名和年龄

--S表(学生表):sno(学号)、sname(学生姓名)、sage、ssex--C表(课程表):cno(课程号)、cname(课程名)、teacher(老师名)--SC表(成绩表):sno、cno、grade(成绩)

select sname,sage fromSwhere sno in(selectS.snofrom S inner join Sc on S.sno =Sc.snogroup by Sc.sno having count(*)>1);

案例3

要求输出每个用户的基本信息、所在的群总数、自己创建的群数、参与别人创建的群数,没有的话数量显示0。

用到的表:

select t1.userPhone,t1.userNickName,t1.userType,TotalNum=ISNULL(t5.TotalNum,0) ,num1=ISNULL(t3.num1,0), num2=(ISNULL(t5.TotalNum,0)-ISNULL(t3.num1,0))from T_ChatUser ast1left join(select t2.groupOwnerId as groupOwnerId , count(*) as num1 from T_ChatGroup ast2group byt2.groupOwnerId

)ast3on t1.id =t3.groupOwnerIdleft join(select t4.userId, count(*) as TotalNum from T_GroupUser ast4group byt4.userId

)ast5on t1.id =t5.userIdorder by t1.addTime desc

五. 实战练习

1. 练习1

--相关表说明

--S表(学生表):sno(学号)、sname(学生姓名)、sage、ssex

--C表(课程表):cno(课程号)、cname(课程名)、teacher(老师名)

--Sc表(成绩表):sno、cno、grade(成绩)

练习题分享:

--相关表说明--S表(学生表):sno(学号)、sname(学生姓名)、sage、ssex--C表(课程表):cno(课程号)、cname(课程名)、teacher(老师名)--Sc表(成绩表):sno、cno、grade(成绩)--一. 测试一--1. 求年龄大于所有女同学年龄的男学生姓名和年龄select sname,sage from S where S.ssex='男' and S.sage >(select Max(sage) from S where ssex='女');select sname,sage from S where S.ssex='男' and S.sage > All(select sage from S where ssex='女');--2.求年龄大于女同学平均年龄的男学生姓名和年龄。select sname,sage from S where ssex='男' and sage >(select Avg(sage) from S where S.ssex='女');--3.求成绩为空值的学生学号和课程号select sno,cno from Sc where Sc.grade is null;--4.检索姓名以 WANG 打头的所有学生的姓名和年龄。select sname,sage from S where sname like 'WANG%';--5.检索学号比 WANG 同学大,而年龄比他小的学生姓名。select sname from S wheresno> (select sno from S where sname = 'WANG')

and

sage< (select sage from S where sname ='WANG');--写法2select S2.sname from S as S1, S asS2where S1.sno=S2.sno

and S1.sname='WANG' and S2.sno>S1.sno and S2.sage

group by cno having count(*) >2order by Num desc,cno asc;--7.求 王森莉 老师所授课程的每门课程的学生平均成绩。--显示内连接 (关键字 inner join on,inner可以省略,推荐写法)selectSc.cno,Avg(Sc.grade)from Sc JOIN C on Sc.cno =C.cnowhere C.teacher='王森莉'group by cno ;--隐式内连接selectSc.cno,Avg(Sc.grade)fromSc , Cwhere Sc.cno = C.cno and C.teacher='王森莉'group by cno ;--8.求选修 数学 课程的学生的平均年龄。select Avg(sage) fromSwhere S.sno in(select Sc.sno from Sc join C on Sc.cno=C.cno where C.cname='数学')--9.统计有学生选修的课程门数。select count(distinct cno) fromSc;--测试二--1. 查询选修课程名称为 数学 的学员学号和姓名select sno,sname fromSwhere sno in(select sno from Sc inner join C where C.cno = Sc.cno and C.cname='数学');--2. 查询选修课程编号为 01的学员姓名和年龄selectS.sname,S.sagefrom S inner join Sc on S.sno =Sc.snowhere Sc.cno ='01';--3. 查询不选修课程编号为 01的学员姓名和年龄selectS.sname,S.sagefrom S inner join Sc on S.sno =Sc.snowhere Sc.cno !='01';--4. 查询只选修了一门课程的学员姓名和年龄select sname,sage fromSwhere sno in(selectS.snofrom S inner join Sc on S.sno =Sc.sno

group by Sc.sno having count(*)>1);--5. 查询选修了课程的学员人数select count(distinct sno) as '数量' fromSc;--6. 查询选修课程超过5门的学员学号和姓名select sno,sname fromSwhere sno in(selectS.snofrom S inner join Sc on S.sno =Sc.sno

group by Sc.sno having count(distinct Sc.cno)>5);--测试三--1. 找出没有选修过“孟家美”老师讲授课程的所有学生姓名selectsnamefromSwhere sno not in(selectSc.snofrom Sc inner join C on C.cno =Sc.cnowhere C.teacher='孟家美');--2. 列出有二门以上(含两门)不及格课程的学生姓名及其平均成绩selectS.sname, Avg(Sc.grade)from S inner join Sc on S.sno=Sc.snowhere Sc.grade<60group by Sc.sno,S.sname

having count(distinct cno)>=2;--3. 列出既学过“ 01 ”号课程,又学过“ 02”号课程的所有学生姓名selectS.snamefromS

inner join Sc on S.sno=Sc.snowhere Sc.cno='01' and S.sno in(selectS.snofromS

inner join Sc on S.sno=Sc.snowhere Sc.cno='02');--4. 列出“ 01 ”号课成绩比“ 02”号课程成绩高的所有学生的学号selects1.snofrom Sc s1 inner join Sc s2 on s1.sno =s2.snowhere s1.cno='01' and s2.cno='02' and s1.grade >s2.grade;--5. 列出“ 01 ”号课成绩比“ 02 ”号课成绩高的所有学生的学号及其“ 1 ”号课和“ 2”号课的成绩select Sc1.sno,Sc1.grade as '01号课成绩',Sc2.grade as '02号课成绩'

fromSc Sc1,Sc Sc2where Sc1.sno =Sc2.sno

and Sc1.cno='01'and Sc2.cno='02'and Sc1.grade>Sc2.grade;--S表(学生表):sno(学号)、sname(学生姓名)、sage、ssex--C表(课程表):cno(课程号)、cname(课程名)、teacher(老师名)--Sc表(成绩表):sno、cno、grade(成绩)--测试四--1. 在基本表 SC 中修改 4 号课程的成绩,若成绩小于等于 75 分时提高 5% , 若成绩大于 75 分时提高 4%(用两个 UPDATE 语句实现)。

update Scset grade=grade * 1.05 where grade <=75 and cno='4';

update Scset grade=grade * 1.04 where grade >75 and cno='4';--2. 把低于总平均成绩的女同学成绩提高 5%

--注:不需要关联查询

update Scset grade=grade * 1.05

where grade < (select Avg(grade) from Sc) and sno in(select sno from S where ssex='女');--3. 把选修数据库原理课不及格的成绩全改为空值--注:不需要关联查询

update Scset grade=null

where Sc.grade<60 and cno in(select cno from C where cname='数据库原理');--4. 把WANG 同学的学习选课和成绩全部删去。--注:不需要关联查询

deletefromScwhere sno in (select sno from S where sname='WANG');--5. 在基本表 SC 中删除尚无成绩的选课元组。

deletefrom Sc where grade is null;--6. 在基本表 S 中检索每一门课程成绩都大于等于 80分的学生学号、姓名和性别,并把检索到的值送往另一个已存在的基本表 S1 (sno,sname,ssex)

insert into S1(sno,sname,ssex)

(select S.sno,S.sname,S.ssex from S inner join Sc on S.sno =Sc.sno

group by Sc.sno having Min(Sc.grade>=80));--或

INSERT INTO S1(sno,sname,ssex) SELECT sno,sname,ssex

FROM S WHERE NOT EXISTS(SELECT*FROM Sc WHERE

grade<80 AND S.sno = Sc.sno or S.sno = Sc.sno and grade is null) and sno in (select sno from Sc)

View Code

2.练习2

--相关表

--UserInfor表: id name age salary

--相关表

--Student_Info(学生表):sno、sname、sex、birthDate、homeAddress、remark

--Curriculum(课程表):cno、cname、cscore(学分)

--Grade(成绩表):sno、cno、grade(成绩)

练习题分享:(待补充)

--测试1--相关表--UserInfor表: id name age salary

--1. 删除姓名、年龄重复的记录,只保留Id最大的一条.--分析:根据姓名、年龄分组,取出每组的Id最大值,然后将Id最大值之外的排除。

--错误写法:不能先select出同一表中的某些值,再update这个表(在同一语句中),即不能依据某字段值做判断再来更新某字段的值!!!

delete from UserInfor where id not in(select Max(id) fromUserInforgroup byname,age);--正确写法:

delete from UserInfor where id not in(select * from(select Max(id) from UserInfor group byname,age) a);--测试2

--相关表--Student_Info(学生表):sno、sname、sex、birthDate、homeAddress、remark--Curriculum(课程表):cno、cname、cscore(学分)--Grade(成绩表):sno、cno、grade(成绩)

--1. 在GRADE表中查找80-90分的学生学号和分数(ok)

select sno,grade fromGradewhere grade between '80' and '90';--2.在GRADE 表中查找课程编号为003学生的平均分(ok)

select Avg(grade) as '平均分'

fromGradewhere cno ='003';--3.在GRADE 表中查询学习各门课程的人数(ok)

select cno,count(*)fromGradegroup bycno;--4.查询所有姓张的学生的学号和姓名(ok)

selectsno,snamefromStudent_Infowhere sname like '张%';--5.查询和学号’0001’的这位同学性别相同的所有同学的姓名和出生年月(ok)

selectsname,birthDatefromStudent_Infowhere sex =(select sex from Student_Info where sno='0001');--6.查询所有选修课程编号为0002 和0003的学生的学号、姓名和性别(ok)

selectS.sno,S.sname,S.sexfrom Student_Info S inner join Grade G on S.sno =G.snowhere G.cno in ('0002','0003');--7.查询出学号为0001的学生的分数比0002号学生最低分高的课程的课程编号和分数(ok)

selectcno,gradefromGradewhere grade >(select Min(grade) from Grade where sno='0002') and sno='0001';--8.查询分数在80-90分的学生的学号、姓名、分数(ok)

selectS.sno,S.sname,G.gradefrom Student_Info S inner join Grade G on S.sno =G.snowhere G.grade between 80 and 90;--9.查询学习了’C语言’课程的学生学号、姓名和分数(ok)

selectS.sno,S.sname,G.gradefrom Student_Info S inner join Grade G on S.sno =G.snoinner join Curriculum C on G.cno=C.cnowhere C.cname='C语言';--10.查询所有学生的总成绩,要求列出学号、姓名、总成绩,没有选课的学生总成绩为空。 (有问题)

select S.sno,S.sname, Sum(G.grade) as '总成绩'

from Student_Info S left join Grade G on S.sno =G.snogroup by G.sno;

View Code

3. 练习3

--相关表

-- Course(课程表):course_id(课程号),name(课程名),teacher_id

-- Score(成绩表):sid(学号)、course_id(课程号)、score(分数)

-- Student(学生表):sid、sname、birthDay

-- Teacher(老师表):teacher_id, name

-- Dept(部门表):dept_id,name

练习题分享:

--涉及的表--Course(课程表):course_id(课程号),name(课程名),teacher_id--Score(成绩表):sid(学号)、course_id(课程号)、score(分数)--Student(学生表):sid、sname、birthDay--Teacher(老师表):teacher_id, name--Dept(部门表):dept_id,name

--1. 查看所有英语成绩超过数学成绩的学生的学号和姓名

Selectaa.sid,aa.snamefrom (Select a1.sid,sname,score from Student a1 inner join Score b1 on a1.sid=b1.sid inner join Course c1 on c1.course_id=b1.course_id where c1.`name`='数学') aainner join (Select a2.sid,sname, score from Student a2 inner join score b2 on a2.sid=b2.sid inner join Course c2 on c2.course_id=b2.course_id where c2.`name`='英语') bbon aa.sid=bb.sidWhere aa.score

select Student.sid,Student.sname,Avg(Score.score)from Student inner join Score on Student.sid =Score.sidGROUP BY Student.sid,Student.sname HAVING Avg(Score.score) >=60;--3. 查询所有同学的学号、姓名、选课数、总成绩

select S1.sid,S1.sname,count(S2.course_id),sum(S2.score)from Student S1 inner joinScore S2on S1.sid =S2.sidgroup byS1.sid,S1.sname;--4. 查询姓zhang的老师的个数

select count(*) from Teacher where name like 'zhang%';--5. 查询没有学过zhangsan老师课程的学生的学号和姓名

selectsid ,snamefromStudentwhere sid not in(selectStudent.sidfrom Student inner join Score on Student.sid=Score.sidinner join Course on Course.course_id=Score.course_idinner join Teacher on Course.course_id=Teacher.teacher_idwhere Teacher.`name`='zhangsan');--6. 查询既学过英语也学过语文的学生的学号和姓名

Select a.sid,sname fromStudent ainner join Score b on a.sid=b.sidInner join Course c on b.course_id=c.course_idWhere c.name in ('英语', '语文')Group by Sid,sname Having count(*)>=2;--7. 查询有学生的单科成绩小于60的姓名和课程名称

selectStudent.sname,Course.`name`from Student inner join Score on Student.sid =Score.sidinner join Course on Course.course_id=Score.course_idwhere Score.score<60;--8. 按平均成绩从高到低显示所有学生的姓名和语文、数学、英语三科成绩

Select c.sname, avg(score) score_avg,sum(case when b.name='语文'then a.score else 0 end) a1,sum(case when b.name='数学' then a.score else 0 end) a2,sum(case when b.name='英语' then a.score else 0 end) a3FromScore ainner join Course b on a.course_id=b.course_idinner join Student c on c.sid=a.sidGroup bya.sidorder by avg(a.score) desc;--9. 查询各科成绩中的最高分和最低分

select course_id,max(score),min(score)fromScoregroup bycourse_id;--10. 计算各科平均成绩和及格率的百分比

Select course_id,avg(score) as '平均分',sum(case when score>=60 then 1 else 0 end)/count(*)*100 as '及格率'

FromScoreGroup bycourse_id--11. 查询不同老师所教的不同课程按照平均分从高到低排列(这里假设一个老师就教一门课)

Select c.name '老师名',b.name '课程名',avg(score) '平均分'

From Score a inner join Course b on a.course_id=b.course_idInner join teacher c on b.teacher_id=c.teacher_idGroup byc.name,b.nameOrder by avg(score) desc

--12. 查询英语和数学课程成绩排名第5到第10的学生的姓名和成绩

(selectStudent.sname,Score.scorefromScoreinner join Student on Score.sid =Student.sidinner join Course on Course.course_id =Score.course_idwhere Course.`name` ='英语'

order by Score.score desclimit4,6)union all(selectStudent.sname,Score.scorefromScoreinner join Student on Score.sid =Student.sidinner join Course on Course.course_id =Score.course_idwhere Course.`name` ='数学'

order by Score.score desclimit4,6)--13. 统计按照各科成绩,分段统计每个课程在90分以上、80-90、60-80、低于60分的人数

Selectb.name,sum(case when score>=90 then 1 else 0 end),sum(case when score<90 and score>=80 then 1 else 0 end),sum(case when score<80 and score>=60 then 1 else 0 end),sum(case when score<60 then 1 else 0 end)FromScore ainner join Course b on a.course_id=b.course_idGroup byb.name;--14. 查看每门课程被选修的学生数

select course_id,count(*)fromScoregroup bycourse_id;--15. 查看只学习了一门课程的学生的姓名和学号

selectStudent.sid,Student.snamefrom Student inner join Score on Student.sid =Score.sidgroup by Student.sid,Student.sname having count(*)=1;--16. 查询名字相同的学生名单和个数

select sname,count(*)fromStudentgroup by sname having count(*)>1;--17. 查询85年之后出生的学生人数

select count(*)fromStudentwhere birthDay > '1985-01-01';--18. 查询每门课程的平均成绩、按升序排序,如果平均成绩相同,按课程ID降序

select course_id,Avg(score)fromScoregroup bycourse_idorder by Avg(score) asc,course_id desc;--19. 查询有不及格学生的课程和不及格学生个数

Select course_id,count(*)FromScoreWhere score<60

Group bycourse_id;--20. 将所有学生姓名中前后的空格去掉

Update Student set sname=ltrim(rtrim(sname));--21. 将所有学生的考试成绩展示为课程名:成绩样式

Select a.sid,concat(b.name,':',a.score)FromScore ainner joinCourse bon a.course_id=b.course_id;--22. 将所有老师的名字差分成姓 和 名 两个字段显示

Select name, substring(name,1,locate(' ',name)-1),substring(name,locate(' ',name)+1,50) from Teacher;

View Code

!

作       者 : Yaopengfei(姚鹏飞)

声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。

声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。

mysql查询第八页_第八节:MySQL之Select指令详解和相关练习相关推荐

  1. mysql 查询和修改组合_## 超详细MySQL常用语句,增删查改

    ## MySQL常用语句,增删查改,安装配置mysql服务 ***#新手博客,应届生,谢谢支持哟 记得点赞关注哟*** ***-----sql常见命令:--------*** 安装服务:mysqld ...

  2. mysql查询结果输出文件_如何将MySQL查询输出保存到文件?

    mysql查询结果输出文件 We can use the MySQL outfile statement to save the query output into a file. This is v ...

  3. mysql slowlog中querytime分析_技术分享 | Slow Query Log 使用详解

    作者:宓祥康 爱可生交付服务部团队 DBA 擅长日志分析.问题排查等:主要负责处理 MySQL 与我司自研数据库自动化管理平台 DMP 的日常运维问题,对数据库及周边技术有浓厚的学习兴趣. 本文来源: ...

  4. mysql支持结构化查询语言_结构化查询语言(SQL)详解之一

    转载自:https://study.qqcf.com/web/168/19166.htm 一.SQL语句的分类 ANSI SQL语句分成以下六类(按使用频率排列): 数据查询语言(DQL):其语句,也 ...

  5. mysql 查询不使用索引_简单的mySQL查询不使用索引

    我有一个非常奇怪的问题与MySQL和简单的查询与简单的索引.我试图使用这个查询: SELECT * FROM `counter_links` WHERE `link_id`=1544;正如你所看到的, ...

  6. mysql查询中使用别名_如何在MySQL选择查询中使用别名?

    要在MySQL中设置别名或替代名称,您需要使用AS关键字.让我们首先创建一个表-mysql> create table DemoTable ( Name varchar(100) ); 使用插入 ...

  7. mysql 查询大于某个时间_有关于mysql 时间作为条件查询,索引失效的问题。

    今天遇到一个时间类型,索引失效的问题,记录一个整个过程. 1.先新建一张表,对create_time 字段添加索引 2.用存储过程向user表中批量插入数据 插入的数据总计为1000条. 3.用cre ...

  8. dapper mysql 预处理_.Net Core中Dapper的使用详解

    Dapper 是一个轻量级ORM框架,在项目中如果对性能比较看中,Dapper是一个不错的选择.接下来我们就来看看如何在项目中使用Dapper. 1.安装Dapper 这里直接使用Nuget安装. 安 ...

  9. mysql的用户名怎么看_怎么查看mysql的用户名和密码

    如果你在安装过程中没有设置用户名密码的话,你可以用root用户名与密码登录数据库:用户名:root 密码为空.如果设置过密码忘记了,那不好意思,不能查看密码,只能查看用户名,因为mysql密码是动态m ...

最新文章

  1. IC/FPGA笔试/面试题分析(七)建立时间和保持时间类型考题汇总分析
  2. 从微博的改版谈网页重构——bigpipe中的页面构建优化
  3. 文本类文件与VS关联-实践
  4. python反序列化总结_单例模式的反序列化总结
  5. DOM 节点的创建、删除、替换
  6. Android ContentProvider 内容提供者
  7. centos mysql 5.6.19_Centos 6.3将Mysql 5.1.61升级为mysql 5.6.19遇到的问题及解决方式
  8. 【Elasticsearch】实用BM25 -第2部分:BM25算法及其变量
  9. 2021-2025年中国超本地服务行业市场供需与战略研究报告
  10. IOS中的多线程之GCD
  11. 组合,聚合,关联,依赖的区别
  12. linux让指定文件具有sudo的权限,Linux学习笔记——使用指定的用户权限执行程序——sudo...
  13. div+css布局实现个人网页设计(HTML期末作业)
  14. 神经网络机器翻译(一)
  15. h5制作 php 开源,PHP源码:2019最新仿易企秀V15.1完整版开源版源码,修复采集功能、新增同行站模板采集等...
  16. 华为鸿蒙vivo,vivo的OriginOS系统开启公测 华为鸿蒙OS迎来劲敌
  17. 你的微信接收消息也会延迟吗?原因居然出在这,一招教你轻松解决
  18. C编译错误,运行错误以及常见问题。
  19. 【VRP问题】基于遗传算法求解带容量的VRP问题matlab源码
  20. spark使用supervisor守护进程

热门文章

  1. 【SCOI 2007】修车
  2. 卡西欧CDP-100对战雅马哈镎-30 - 数码钢琴的比较
  3. C/C++程序员给大家示范一下,怎么在七夕表白
  4. STM32 FSMC基地址详解
  5. 伊豆:把豆瓣网装进口袋 伊豆:把豆瓣网装进口袋
  6. 《Java SE实战指南》05-09:语句(Statements)
  7. 【C/C++】面经总结和心得分享
  8. mysql查找top k_查询分页-----强势top
  9. 测试cpu多核性能软件,CPU多核项目大比拼 Corona渲染器测试
  10. busybox编译时编译器的选择