!!! SQL 数据库开发基础 传智!

SQL数据库开发和ADO.net

 

 

DBMS 数据库管理系统

1.分类 Database(不同类放到不同的数据库里)

2,表table (列名(人的字段) 每一行就是一个对象(人))

 

 

主键(Primary): (唯一标识行,避免重复字段分不清楚)

1)业务主键(不常用很难保证不重复) 身份证号,工号...

2)逻辑主键(常用) (没有任何意义完全给计算机看的,工 作人员不会去管它的) 流水号(不是工号,工号可以被重复利用给别 人)

 

外键(ForeignKey): 主键表的外键指向关联表的主键

 

 

 

 

SQLServer的管理

Express 免费版

服务器名称 .(代表本机装的) /local/sql服务器IP地址

身份登入 windows / Sqlserver

建立数据库--新建表--设计表--编辑表

 

 

 

数据类型

                                                                                                bit(0,1)相当于布尔

char(10) (如果填的数据不满足自身的长度,会用字符填 充,而varchar(可变字符串)则是放多少就是多少)

datatime int(32位) bigint(64位)

nvarchar(50)(“无限大的字符串” 可能含有中文,日 文...)

varchar(50)(不含有中文...等信息的字段类型)

 

 

 

 

 

SQL基础

SQL语句(和数据库交谈的语句国际标准的语句,不论什么数据库都得认这 个语句)

字符串:用单引号 书写:语句内容大小写不敏感,但本身放入的值是大小写敏感的

Creat table mydb int not null ,name nvarchar(50) 创建一个表

drop table mydb 删除一个表 insert into mydb(name,)

 

SQL主要分: DDL(数据定义语言)DML(数据操作语言) 两类

Creat table drop table等属于DDL, insert select等对数据本身进行 操作的属于DML 

主键设置 (两种类型)int(或bigint)整数和uniqueidertifier(又称 Guid.UUID)

一般用id做主键名字就行;

int(或bigint)整数自动增长:再设计中标识规范设为是主键值将自动增 长,可以改增长跨度但一般不需要改;一个标只能有一个标识列,解决并发 事情,防止两个人同时往这个表里填数据

优缺点

int(或bigint)整数优点:占用空间小,生成过程不需要开发人员干预; 好读 缺点:效率低数据导入导出困难;

GUID优点:效率高不需要借助其他操作;GUID (取之不尽用之不竭) 缺点:占用空间大,不好读; 业务逐渐倾向于GUID C#代码显示Duid id=GUID.newguid()

 

标识列表添加数据:

insert into mydb(,列名,,)value(值,,,) 列明可 以省略知道就行,尽量不要省略,省略对id的操作,因为自增长列, 

Guid列表添加操作添加:insert into mydb(id,列名,,)value(newid(),值,,,) 需 要开发人员干预 ,操作不用指定主键 每个字段都可以设默认值:默认值可以是newid()可以自动生成,但很少这 么用 修改:

更新数据 Update t_name Set 列=‘值’,,Age=Age++//表达式 Update t_name Set name=n'青年人' where Age<>20 中文前面最好加n可 能会出错 <>不等于号 or 或 between and并且 not非

删除数据

Delete from t_name where id=3 清空数据(与Drop不同)

 

 

 

检索select(主要语句)

一:select*from t_name

select 列名(字段名) as 姓名 from t_name where code=3 //as别名 设置,Where过滤语句

备注:跟表不相关的都可以,非常灵活:

select getdate()当前时间 select 1+2+”“+”cs23“ 可计算

二:聚合函数(对某个字段进行操作计算,对结果进行的操作):

select count(*),Max(gongzi),min(),sum(),Aug() from where gongzi>5000

三:数据的排序

select*from t_name where id=2 order by Age asc(升序由小到大) ,工 资desc(降序) 先按Age排序结果再按工资排序

注意:where在 order by 之前

四:模糊查询(通配符查询)有两种

一种:单字符通配符"_"半角下划线

select*from t_name where name like"_emcn"

第二种:多字符通配符半角百分号”%“他匹配任意次数(0或多个)出现的任 意字符 "k%"匹配以k开头的任意长度的字符串

select*from t_name where name like"k%"

检索姓名中包含字母”n“的员工信息 select*from t_name where name like"%n%"

 

 

 

Null:

在sql中表示不知道而不是表示没有值 ,有Null参与的运算结构都是null( 不知道) 如何查询(is Null/is not Null)

select*from t_name where name is Null

多值匹配 select*from t_name where Age =30 or Age=50 or Age=20

select*from t_name where Age in[23,25,34]

select*from t_name    where   Age >30  and  Age30   group by   chengji    

select不能使用没有出现在group by子句里面的字段(列名) ,必须是聚 合函数和group by中出现的字段 group by 按照某个字段进行分组后查询,having子句必须放在where之后

 select count(*) from t_name where Age group by age having count (*)>1 聚合函数不能出现在where子句中,having必须出现在group by后面, having是对分组后结果操作的,字段必须是和select中能用的是一样, where是对原始数据的过滤

 

限制结果集范围(行数)

select  top 10  from t_name order by gongzi desc

子查询(常用于分页查询):select top3 id from t_name where id not in(selec top 5 id from t_name order by gongzi desc)

抑制重复数据(distance去重查询)

selec distinct from t_name order by gongzi desc

注意:过滤的是整行重复的

联合结果集(Unoin all)

selec*from t_临时工

Union

selec*from t_正式工

将两个结果合为一个结果(两个表的所有结果) 把重复数据自动去除相当 于distinct

注意:列名(字段)个数一样和类型相同 个数不足需要补足:

selec name,bumrnfrom t_临时工

select name ,’临时工无部门'from t_正式工  all全部显示

selec*from t_临时工

Union all

selec*from t_正式工

注意:all全部显示,无特殊理由不要去除all

 

案例: 查询所有员工工资最大值和最小值,区分临时工和正式工

select '正式员工‘,max(Age) from t_name

Union all

select '正式员工‘,min(Age) from t_name

Union all 

select '正式员工‘,max(Age) from t_name

Union all

select '正式员工‘,min(Age) from t_name

案例2: 查询美每位式员工的信息,包括工号、工资,并且在最后一行加上所有员工 工资额合计。

select gonghao ,gongzi from t_name  

Union

select '工资合计',sum(gongzi)from t_name

 

 

数据库函数

 

ABS():                       求绝对值 selectABS(-3)

CELLING():                    舍入到最大整数 3.33将被舍入为4、2.89将会舍入为3、-3,61将 被舍入为-3,celling --天花板 FLOOR()舍入为最小整数 3.33将被舍入为3、2.89将会舍入为2、-3,61将被 舍入为-4 floor--地板

ROUND()                       四舍五入。 舍入到离我“半径”最近的数

round()--                      半径 round(3.1415926,0) 两个参数后一个参数是精度

LEN():                       计算字符串的长度

LOWER()/UPPER();       转小写、大写

LTRIM()                        字符串左侧的空格去掉

RTRIM()                        字符串右侧的空格去掉

LTRIM(RTRIM())          去掉两边空格

SUBSTRING(’‘,,)

GETDATE():当前日期 DATEPART(datepart.number,date) DATE ADD(getdate,-3)

DATE DIFF(差额代表数,开始日期,最后日期)

select Date Diff(year,FinDate,getdate())count(*)from T_name group by Date Diff(year,FinDate,getdate()) DATEPART(datepart,date) 返回一个日期的特定部分

 select Datepart(year,FinDate)count(*) from t_name group by Datepart(year)

 

 

 

 

类型转换函数

CAST(expxession被转换的表达式 As date_type数据类型)

CONVERT(date_type,expxession)

SELECT Fldnumber RIGHT(Fldnumber,3)AS 后三位

CAST(RIGHT(Fldnumber,3)AS INNERGER)+AS 后三位的整数形式

CAST(RIGHT(Fldnumber,3)AS INNERGER)+1 AS 后三位加1

CONVERT(INNERGER.RIGHT(Fldnumber,3)/2 AS 后三位除以2 备注:所有函数都可以写字段

 

 

 

 

 

流控函数(控制处理函数)

isnull (expression,value)不为空则返回expression否则返回value

 

select isnull (Fname,'佚名')as 姓名from T_employee

 

 


CASE函数应用法


单值判断,相当于switch case
case expression
When value1 then returnvalue1
When value2 then returnvalue2
When value3 then returnvalue3
else defaulttreturnvalue
End

 

例子:select Fname,

(Case flevel
when 1 then 'VIP客户'

 

when 2 then '高级客户'

 

when 3 then '普通客户'
else'客户类型错误'
END)as FlevelName from T_Customer

 

 

练习一:表中有ABC三列,用SQL语句实现;当A列大于B列时选择A列否则选
择B列,当B列大于C列时选择B列否则选择C列
select (case when a>b then a else b end),(case when b>c then b
else c end)

 

 

练习二有一张表,记录比赛成绩
Date Name Score
2008-8-8 拜仁 胜
2008-8-9 奇才 胜
2008-8-9 湖人 胜
2008-8-10 拜仁 负
2008-8-8 拜仁 负
2008-8-12 七彩 胜
要求输出下面格式
Name 胜 负
拜仁 1 2
湖人 1 0
奇才 2 0
注意在中文字符串前面加‘N’,比如N‘胜’
select Name,
Sum(
case Score
when N'胜' then 1
else 0
end
)as 胜,

 

Sum(
case Score
when N'负' then 1
else 0
end
)as 负,
from T_Score group by Name

 

 

练习三

 

单号 金额
Rk1 10
Rk2 20
Rk3 -30
Rk4 -10
将上面的表输出为如下格式:
单号 收入 支出
Rk1 10 0
Rk2 20 0
Rk3 0 30
Rk4 0 10
select Fnumber,
(
case
when Famount>0 then Famount
else 0
end
)as 收入,

 

(
case
when Famount<0 then ABS(Famount)
else 0
end
)as 支出,
from t_test 1

 

终极练习:创建一张表,记录电话工作员的电话流水,记录呼叫员编号、对方号码、通话开始时间、通话结束时间、建表、插数据等最后都自己写SQL语句
要求:
输出所有数据中通话时间最长的5条记录。    order by /date diff
输出所有数据中拨打长途号码(对方号码以0开头)的总时间长    like、sum
输出本月通话总时长最多的前三个呼叫员的编号。    date diff(month...),sum.orderby
输出本月拨打电话次数最多的前三个呼叫员的编号      group by ,count(*)
输出所有数据的拨号流水,并且在最后一行添加总呼叫时长
1)呼叫员编号、对方号码、通话时长
2)......
3)汇总【市内号码总时长】【长途号码总时长】

 

 

输出所有数据中通话时间最长的5条记录。
select top 5from t_callrecords1 order by datediff(second,Startdatetime,enddatetime) desc

输出所有数据中拨打长途号码(对方号码以0开头)的总时间长
select sum(datediff(second,Startdatetime,enddatetime))from t_callrecords1 where telnum like'0%'

输出本月通话总时长最多的前三个呼叫员的编号。

select datediff(month,convert(datetime,2010-06-01)),convert(datetime,'2010-07-02')),datediff(month,convert(datetime,2010-06-15)),convert(datetime,'2010-07-02'))

 

select Callernumber,telnum,datediff(month,stardatetime,getdate())from t_callrecords1

 

select*from t_callrecords1

where datediff(month,startdatetime,getdate())=0

 

 

select top3 allernumber from t_callrecords1
where datediff(month,startdatetime,getdate())=0
group by callernumber
order by sum(datediff(second,dtartdatetime,enddatetime))desc

 


输出本月拨打电话次数最多的前三个呼叫员的编号
select top 3 callernumber,count(*)from t_callrecords
where datediff(month,startdatetime,getdate())=0
group by callernumber
order by count(*)desc


输出所有数据的拨号流水,并且在最后一行添加总呼叫时长
select callernumber,telnum,datediff(second,startdatetime,enddatetime)
from t_records1
union all
select '汇总'
convert(varchar(50),
sum((
case
when telnum not like'0%' then datediff(second,startdatetime,enddatetime)
else 0
end
))
)as 市内通话,
sum((
case
when telnum like'0%' then datediff(second,startdatetime,enddatetime)
else 0
end
))
)as 长途通话,
from t_callrecords1
))

 

索引Index
1,全表扫描(了解):对数据进行检索(select)效率最差的就是全表扫描,也就是一条条的找
打个比方,翻看字典,如果没有目录我们要一页一页的查找,而有了目录查询目录即可,为了提高检索的速度,可以为经常检索的列添加索引,相当于创建目录。
2,创建索引的方式:在表设计器中右键,选择“索引/键”——添加——在列中选择索引包含的列
3索引优缺点:使用索引提高查询效率,但是索引也是占据空间的,而且添加、更新、删除数据的时候也需要同步更新索引,因此会降低Insert、Update、Delete的速度。所以尽量只在经常检索的字段上(where)创建索引

注意:即使是创建了索引,仍然有可能全表扫描,比如Like、函数、类型转换等。

 

 

JOIN
表连接join(关联查询)

 

练习说明:有客户表(t_kehu)和订单表(t_dingdan)两个表,客户表字段为:Id、Name、Age,订单表字段为:Id、Billno、customerld,订单表通过customerld关联客户表。

select o.Billno,C.name,c.Age
from T_dingdan as o
join t_kehu as c on o.customerld=c.id

要求显示所有年龄大于15岁的顾客买的订单号、客户姓名、客户年龄。
要求显示年龄大于平均年龄的顾客购买的订单

备注:其他形式:Innner Join 、left join 、right join

 

 

 

 


子查询

概念:讲一个查询语句作为一个结果集供其他SQL语句使用,就像使用普通的表一样,被当做结果集的查询语句被称为子查询,所有可以使用表的地方几乎都可以使用子查询来代替。select*from(select*from t2 where fage<30)

 

单值作为子查询:select 1 as f1,2,(select min(FYearpublished)from t_book) as f4
只有返回且仅返回一行/一列数据的子查询才能当成单值子查询。下面是错误的:select 1as fi,2,(select fyearpublished from t_book)
select*from t_readerfavrite where fCategoryld=(select fld from t_category where fname='story')

 

1、如果子查询是多行单列的子查询,这样的子查询的结果集其实是一个集合
select*from t_reader
where fyearofjoin in(2001,2003) in()//在(此)范围内
select*from t_reader
where fyearofjoin in
(
select Fyearpublished from T_book
)
2、限制结果集。返回第三行到第五行的数据
select*from
(
select Row_number() over(order by Fsalary desc)AS rownum,fnumber,fname,fsalary,fage from t_employee
)as a
where a.rowmun=>3 and a.rownum<=5

 

Row_number开窗函数 行号  可代替top
备注:把查询结果当做子查询最常用的方法——分页查询
注意:只能出现在select 、 order by 中 不能出现在Where中

posted on 2015-11-23 14:20  闫科达  阅读(286)  评论(0编辑  收藏  举报

导航