学习MS SQL Server

SQL语句对两个表的数据进行的检查:

人员基础信息表:

SQL语句

说明

select 记录总数=count(*) from  memberbaseinfo

20353条记录

|

鉴定结果表:

SQL语句

说明

select 记录总数=count(*) from  jdjg

总记录数:48581

select distinct c02 as "姓名" from jdjg

不同的姓名:19383

select distinct c01 as 身份证号码  from jdjg

不同的身份证号码:18104

select distinct c01,c02 from jdjg

C01和c02组合不同:21920

select c01 from jdjg group by c01 having  count(*)>1

有重复[身份证号码]记录数:12319

select c02 from jdjg group by c02 having count(c02)>1

有重复[姓名]的记录数:11758

select c01,count(distinct c02) from jdjg group by c01 having  count(c01)>1 and count(distinct c02)>1

身份证号码相同而姓名不同的身份证号码个数:2697

select c01 身份证号码,c02 姓名 from jdjg where c01 in ( select c01 from jdjg group by c01 having  count(c01)>1 and count(distinct c02)>1) order by c01

列出身份证号码相同而姓名不同的记录明细:12093

select c02,count(distinct c01) from jdjg group by c02 having  count(c02)>1 and count(distinct c01)>1

姓名相同而身份证号码不同的记录:1262

select c01,max(c23) from jdjg group by c01 order by c01

找出每个人最新的鉴定时间:18104

select c01 姓名,c19 考试分数,c22 鉴定结果,c23 鉴定时间  from jdjg where c23>'2012-1-1'

找出今年鉴定的记录:4630

select c01 身份证号码,c02 姓名,c19 鉴定成绩,c22 鉴定结果,c23  鉴定时间 from jdjg where c23>'2012-1-1' and c19 is  null

找出今年以来没有填写成绩的记录:524

select c01 身份证号码,c02 姓名,c19 鉴定成绩,c22 鉴定结果,c23  鉴定时间 from jdjg where c23>'2012-1-1' and c19<60

列出今年以来不合格的人员名单:1207

select c01 身份证号码,c02 姓名,c19 鉴定成绩,c22 鉴定结果,c23  鉴定时间 from jdjg where c23>'2012-1-1' and c19>=60

列出今年以来合格的人员名单:2899

select c02 from jdjg where c01 in ( select top 100 c01 from  jdjg where c23>'2012-1-1' group by c01 having count(*)>=2 order by  count(*) DESC) and c23>'2012-1-1' group by c02

今年以来考过两次以上的人员:32

|

1、检查在鉴定结果表中存在的身份证号码在人员基础信息表中不存在的记录数

SQL语句

说明

select count(*) from jdjg where c01 not in ( select c01  from memberbaseinfo )

4866条记录

select c01,c02 from jdjg where c01 not in ( select c01 from  memberbaseinfo ) order by c01

列出明细记录

2、检查在鉴定结果表中存在的姓名在人员基础信息表中不存在的记录数

select count(*) from jdjg where c02 not in ( select c02  from memberbaseinfo )

9878条记录

select c01,c02 from jdjg where c02 not in ( select c02 from  memberbaseinfo ) order by c01

列出明细

3、检查在鉴定结果表和人员基础信息表中单位名称不一致的情况

select a.c01,a.c02,a.c03+a.c04+a.c05 "人事信息中的单位",b.c03+b.c04+b.c05 "鉴定结果表中的单位"  from memberbaseinfo a ,jdjg b where  a.c03+a.c04+a.c05<>b.c03+b.c04+b.c05 and a.c01=b.c01

13350条记录

4、对身份证号码的检查

select c01,c02 from jdjg where patindex('%[吖-座]%',c01)>0

包含汉字

Select c01,c02 from jdjg where patindex('%[a-zA-Z]%',c01)>0

包含字符

5、对姓名的检查

select c01,c02 from jdjg where patindex('%[0-9]%',c02)>0

包含数字

Select c01,c02 from jdjg where  patindex('%[a-zA-Z]%',c02)>0

包含字符

|

Select语句:

SELECT Select_list

[WITH <Common_table_expression> ]

[INTO New_table]

FROM Table_source

[WHERE Search_condition]

[GROUP BY Group_by Expression]

[HAVING Search_condition]

[ORDER BY Order_expression[ASC|DESC]]

关键词

说明

注意点

Select_list

查询结果输出列,可以指定FROM指定表中的一个或多个字段,还可以是由字段、常量与函数所组成的表达式。

DISTINCT:用于选择数据表中的唯一记录,每个SELECT语句只能有一个DISTINCT关键字。如果DISTINCT后面跟有多个字段,则要多个字段的组合相同才被看作重复记录;每个SELECT语句只能包含一个DISTINCT关键字。

INTO

查询结果输出,可用于建新表。

输出列中不能包含计算列

FROM

查询的表名。

为了使语句清晰而使用表的别名

WHERE

查询条件。

GROUP BY

显示group by 子句所产生组的全部结果,没有的值用NULL填充。

HAVING

为Group by子句产生的分组提供细分条件,having子句用来搜索分组数据。

Having 是组内而Where是针对表

ORDER BY

ORDER BY 语句用于在输出的结果集中对指定的列进行排序。默认是按照升序对记录进行排序,可以是一个字段或表达式。

Asc:升序;Desc:降序

|

运算符

符号

说明

举例

IN

判断数据记录是否出现在指定的各个数据值中

select c01 身份证号码,c02 姓名 from memberbaseinfo where c07 IN ('哈萨克族','维吾尔族','藏族');

BETWEEN

判断数据在指定范围内,可判断日期;

选择出年龄在30-35岁之间并且本星期过生日的人:

select c02 姓名,c09  出生日期 from memberbaseinfo where  month(c09)=month(getdate())and ( day(c09) BETWEEN 26 and 30 ) and (  datediff(year,c09,getdate()) between 30 and 35 );

LIKE

用于在WHERE 子句中搜索指定条件。

|

通配符:

*

表示源表中所有字段

%

替代一个或多个字符,只能用在where子句中,表示0个或0个以上的字符,通常和运算符like配合使用。

_

仅替代一个字符,只能用在where子句中,通常和运算符like配合使用。

查找姓名第三字为“军”或为“丽”、身份证号码第一位在0~3之间且第4位在6~9之间、姓“李”或“张”的记录:

select  c01 身份证号码,c02 姓名 from  memberbaseinfo where ( c02 like '__华%' or c02 like  '__丽%' ) and c02 like '[李张]%'  and ( c01 like '[0-3]__[6-9]%' );

[]

字符列中的任何单一字符,只能用在where子句中,用来限定单个字符介定于指定的范围或集合中,通常和运算符like配合使用。

下面的语句找出名字中第一个字符为P—Z之间,后面字符为inger的人名:

[^]

只能用在where子句中,用来限定任何单个字符不介定于指定的范围或集合中,通常和运算符like配合使用。

[!]

不在字符列中的任何单一字符

|

常用聚集函数 {[all|distinct]expression}|*

函数名

说明

举例

Count()

统计记录数

统计各个工龄的人数:

SELECT count(*) 人数,datediff(yyyy,C10,getdate())  工龄 from memberbaseinfo group by c10 order by  datediff(yyyy,C10,getdate());

统计性别的人数:

select count(*),CASE C06

WHEN '1' THEN '男'

WHEN '2' THEN '女'

ELSE '其他' END

from memberbaseinfo group by C06

min()

计算一列中expression的最小值。

计算人员中的最大年龄:

select year(getdate())-year(min(c09)) as 最大年龄 from memberbaseinfo

或:

select datediff(yyyy,min(c09),getdate()) as 最大年龄 from memberbaseinfo

max()

计算一列中expression的最大值。

计算人员中的最大工龄:

select  max(datediff(yyyy,c10,getdate())) as 最大工龄 from  memberbaseinfo

avg()

计算一列中expression的平均值

计算男性员工的平均年龄:

select  avg(year(getdate())-year(c09)) as 平均年龄 from  memberbaseinfo where c06='男'

计算女性员工的平均年龄:

select  avg(datediff(yyyy,c09,getdate())) as 平均年龄 from  memberbaseinfo where c06='女'

SUM()

统计表达式中所有项的总和

|

注意点:

1

比较字段中的NULL值用is null 或is not null;

2

’[1-4]%’表示1到4之间,而’[14]%’表示1或4

3

SQL用单引号来环绕文本值,如果是数值不要使用引号。如果字段中包含_或者%等特殊字符的话用以下语句:用escape,\转移字符,表示其后的字符是常量。

查找身份证号码里包含了“%”或“_”的记录:

select c01  身份证号码,c02 姓名 from memberbaseinfo where ( c01 like '%\%%' escape '\' ) or ( c01  like '%\_%' escape '\' ) ;

4

可以直接进行函数练习:

Select substring('SQL  Server 2000',1,3)

Select right(left('SQL  Server 2000',10) ,6)

Select left('SQL Server  2000',10)

Select len('hello SQL  Server 2000')

select replace('SQL Server  2000',' ','-')

 

前面用SQL语句检查表的情况,为了重复使用增加灵活性,用存储过程写下来。

/*

查找两个表身份证号码、姓名、工作单位不一致的情况

*/

CREATEPROCEDURE [DBO].[CheckTable_SFZ_XM_DWMC]

@T1varchar(40),--表1名称[主表]

--表1字段

@SFZ_T1varchar(20),--身份证号码

@XM_T1varchar(20),--姓名

@DWMC1_T1varchar(40),--一级单位

@DWMC2_T1varchar(40),--二级单位

@DWMC3_T1varchar(40),--部门名称

@T2varchar(40),--表1名称

--表2字段

@SFZ_T2varchar(20),--身份证号码

@XM_T2varchar(20),--姓名

@DWMC1_T2varchar(40),--一级单位

@DWMC2_T2varchar(40),--二级单位

@DWMC3_T2varchar(40) --部门名称

 AS

declare@Sqlstr varchar(1000)

--检查T1表的身份证号码相同而姓名不同的情况

--set@Sqlstr='select '+@SFZ_T1+'  身份证号码,'+@XM_T1+' 姓名 from '+@T1+' where'+@SFZ_T1+' in ( select '+@SFZ_T1+' from '+@T1+' group by '+@SFZ_T1+' havingcount(1">'+@SFZ_T1+')>1 and count(distinct1">'+@XM_T1+')>1) order by '+@SFZ_T1

--print@Sqlstr

--exec(@SQLStr)

--两个表对比检查

--1、检查在T2表中存在的身份证号码在T1表中不存在的记录

--set@Sqlstr='select '+@SFZ_T2+' 身份证号码 , '+@XM_T2+' 姓名 from '+@T2+' where'+@SFZ_T1+' not in ( select distinct '+@SFZ_T1+' from '+@T1+' ) order by'+@SFZ_T2

--print'检查结果'

--exec(@SQLStr)

--2、检查在T2表中存在的姓名在T1表中不存在的记录

--set@Sqlstr='select '+@SFZ_T2+' 身份证号码,'+@XM_T2+' 姓名 from '+@T2+' where'+@XM_T2+' not in ( select distinct '+@XM_T2+' from '+@T1+' ) order by'+@SFZ_T2

--exec(@SQLStr)

--3、检查在T2表和T2表中单位名称不对应的记录

set@Sqlstr='select a.'+@SFZ_T1+' 身份证号码,a.'+@XM_T1+' 姓名,a.'+@DWMC1_T1+'+a.'+@DWMC2_T1+'+a.'+@DWMC3_T1+'  表1中的单位,b.'+@DWMC1_T2+'+b.'+@DWMC2_T2+'+b.'+@DWMC3_T2+'  表2中的单位 from '+@T1+' a ,'+@T2+' b wherea.'+@DWMC1_T1+'+a.'+@DWMC2_T1+'+a.'+@DWMC3_T1+' <>b.'+@DWMC1_T2+'+b.'+@DWMC2_T2+'+b.'+@DWMC3_T2+'and a.'+@SFZ_T1+'=b.'+@SFZ_T2

--print'检查结果'

exec(@SQLStr)

GO

--执行

--CheckTable_SFZ_XM_DWMC'MEMBERLIST','c01','c02','c03','c04','c05','KWSS','c01','c02','c03','c04','c05'

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值