zoukankan      html  css  js  c++  java
  • 数据库

    数据库
    第二章
    1 执行顺序
    from-->on-->where-->group by-->having-->select(over,distinct,top)-->order by
    2 from
    在逻辑处理阶段第一个要处理的查询子句
      where
    过滤from阶段返回的行,只有能让逻辑表达式,从而过滤由from阶段返回给后续查询处理阶段,
    3 group by
    逻辑查询处理阶段返回的行按组进行组合,在group by阶段包括(having,select,order by)的操作对象将是组,而不是单独的行,每个组最终也表示为查询结果集中的一行,这意味着在group by阶段处理的子句中的所有表达式务必保证为每个组只返回一个标量(单值)
    一个元素如果不在group by列表中出现,就只能作为聚合函数(count,sum,avg,min,max)
    4 having
    过滤group by 分组以后,返回逻辑表达式为True的组
    5 select
    尽量不要使用星号
    6
    order by

    排序
    当指定了distinct以后,order by子句就被限制为只能在select列表中出现的那些元素,这一限制背后的原因是,当指定distinct时候,一个结果行可能代表多个原始行,所以无法清楚的知道应该使用 order by 列表值中多个可能值中的哪一个
    7
    top
    是 T-Sql特有的,用来限制返回的行数和百分比,当查询指定了order by 子句时候,top将依赖该子句定义行的逻辑优先顺序
    top(1) percent-百分之一
    top(5) with ties 表示要增加与orderby子句中条件相同的其他所有行
    8
    over

    over没有条件说明包含所有的记录

    select custid,val,sum(val) over() as orderTotalVal,100.*val/sum(val)over()
    from sales.ordervalues

    select custid ,val ,sum(val) over(partition by custid) as myordertotalval,100.*val/sum(val) over(partition by custid)
    from sales,ordervalues

    partition by 分区


    为行定义了一个窗口,称为开窗函数,
    聚合函数和排名函数都支持over子句的运算类型
    partition by 分区
    排名函数中必须得有orderby子句
    列入
    row_number(order by val)as rownum
    rank 表示之前有多少行具有更低的排序值,表示(1,1,1,1,4 表示五个学生前四个成绩一样)
    dense_rank 表示之前有多少个更低的排序值(1,1,1,1,2 表示排名连续
    ntile装桶

    ntile(2),分了两个组


    9
    case
    简单表达式:将一个值与一个组可能的取值进行比较,并返回第一个匹配的结果,如果列表没有值等于测试值,则case表达式就返回else子句中列出的值
    case categoryid
    when 1(就是说当categorid=1时候) then '...'
    else'...'
    end as ...
    fromy
    搜索表达式
    case
    when val<1000(直接写字段与要求的数做比较) then
    'less then 1000'
    else'...'
    end as ...
    from ...

    10
    null

    三值逻辑
    true false unknow
    where 字段<>...
    or 字段 is null
    聚合函数会忽略空
    尤其是count数数时候

    11
    字符串提取

    可以将 concat_null_yields_null 的会话选项设置为off
    就可以改变SQl server 处理串联的方式
    substring(string,(自己指定的字符串位置)start,(指定所去字符串的长度)length)
    取字符串
    select substring('abcde',2,3)
    返回'bcd'
    left 和(string,n)
    指的是字符串左数起n个字符
    left('abcde',3)
    返回cde
    len和datalength
    select len('abcde')
    返回5(字符)
    select datalength('abcde')
    返回10(字节)
    charindex(substring,string,[start_pas])
    select charindex(' ',' avx csdf',2)
    返回5(表示第二个格的位置是在字符串第五个)
    patindex(pattern,string)
    patindex('%[0-9]%','affsaf123df')
    返回7(表示在字符串中第一次出现数字的位置)
    replace(string,substring1,substring2)
    replace('a-a b-3','-',':')
    返回的结果是(a:a b:3)
    replicate('abc',3)
    将字符串'abc'复制3次
    返回'abcabcabc'
    select supplierid,
    right(replicate('0'9)+cast(supplierid as varvhar(10)) ,10) as strsupplierid
    from production.suppliers;
    stuff
    删除插入
    stuff(string,pas,delete_length,indertstring)
    select stuff('xyz',2,1,'abc')
    返回'xabcz'
    指的是把y删除用'abc'替换
    upper 大写 和 lower 小写

    11
    like 谓词
    %表示任意多个任意字符
    _表示任意一个任意字符
    where lastname like'_d%'
    表示第二个字符为d的所有雇员姓名

    12
    日期函数
    dateadd
    为输入的时间值增加指定的数量
    select dateadd(year,4,'20060404')
    返回
    2010-04-04 00:00:00
    datediff
    返回两个日期和时间值之间相差的指定部分的计数
    select
    dateadd(month,datediff(month,2010-1-31,orderdate),2010-1-31)
    表示查询每月最后一个天的订单情况

    datepart
    select datepart(month,'20090201')
    返回2(代表月份,但是返回的是数字)

    datename
    select datename(month,'20090201')
    返回(取决于当前会话的语言,如果是英语,则返回
    February)

    isdate
    select isdate('20090201')
    表示如果能把括号中的字符串转换成日期,则返回1
    如果不能则返回0

    getdate
    是获取系统当前时间
    在T-sql中才能用

    标准是
    current_timestamp

    12
    数据字典
    元数据
    描述数据的数据
    通常以表的方式提供
    查询特殊的表,数据字典来完成
    oracle 提供一些系统的表或者视图
    有的提供一些特殊命令查询

    查询架构
    select schema_name(schema_id)as sc
    hemaname,name
    from sys.tables

    查询表的结构
    select *
    from sys.columns
    查询指定表的列
    where object_id=Object_id(N'sales.order','U')
    --用标准方法查询

    查询表
    select TABLE_SCHEMA ,TABLE_NAME
    from INFORMATION_SCHEMA .TABLES
    where TABLE_TYPE =N'base table'


    第三章
    连接查询
    1
    交叉连接


    2内链接
    第一步,交叉连接,第二步过滤
    inner join

    3外连接
    第一步,交叉连接,第二步过滤,第三部增加外部行
    left join,right join,full join

    4
    不等连接
    一般在自连接中使用
    表示去掉了不与本身做连接的行
    select e1.empid ,e1.firstname,e2.empid,e2.firstname
    from HR.Employees e1 inner join HR.Employees e2
    on e1.empid <>e2.empid
    但是还存在左行和右行交换重复
    比如 1,2和2,1
    所以应该改为
    select e1.empid ,e1.firstname,e2.empid,e2.firstname
    from HR.Employees e1 inner join HR.Employees e2
    on e1.empid < e2.empid

    5
    null
    --2007年1月一号以后的
    --如果增加的外部行为 null 不能做运算 要在写个or条件
    select companyname ,orderid ,orderdate
    from Sales.Customers c left join Sales.Orders o
    on c.custid =o.custid
    where orderdate >'20070101' or orderdate is null

    6--
    2007年1月一号以后的订单总记(子查询)

    select
    DATEADD(DAY,n.number-1,CAST('20070701'as datetime)) as orderdate,
    isnull((o.total),0) as total
    from
    (select top(31) orderdate ,day(orderdate) as k,
    SUM (od.qty *od.unitprice) as total
    from Sales.Orders o
    inner join
    Sales.OrderDetails od
    on o.orderid =od.orderid
    where year(orderdate) =2007 and MONTH (orderdate )=7
    group by orderdate
    order by orderdate
    ) o  right join (select top(31) p.productid number
    from Production.Products p
    order by number
    ) n on o.k =n.number


    第四章

    -独立子查询
    1 必须放在圆括号里
    单值子查询可以写在任何地方,只需当个值来运算,
    select,where,from,having,
    多值只需改个运算符来个
    多值子查询中 in ontin
    distinct可以省略
    -相关子查询
    查询每个顾客订单号最大的那个订单

    第五章

    表表达式

    1
    派生表
    写在from中子句中的命名子查询
    查询每个顾客的参与的活动的最后一天下过的所有订单
    --1不保证顺序
    --2列有别名
    --3列名唯一
    select o.custid,o.orderid,o.orderdate,o.empid
    from sales.orders o inner join
    (select custid, Max(orderdate) as maxorder
    from sales.orders
    group by custid
    ) oc
    on o.custid =  oc.custid
    and
    o.orderdate=oc.orderdate

    2 cte 公共表表达式 都是一次性的
    查询订单最后一天的订单

    with custlasday
    as
    (
    select custid, Max(orderdate) as maxorder
    from sales.orders
    group by custid
    )
    select o.custid,o.orderid,o.orderdate,o.empid
    from sales.orderd o inner join
    custlasday c
    on o.custid =c.custid
    and orderdate = oc.ordredate

    查询客户订单最多的客户

    with custorderNum
    as
    (
      select custid ,COUNT (*) as ordernum
      from Sales.orders
      group by custid
     
    ),
    custMaxorderNum
    as
    (
    select top(1) custid
    from custorderNum
    order by ordernum desc
    )
    select o.custid ,orderid ,orderdate,empid
    from Sales.Orders o
    inner join custMaxorderNum
    on o.custid =custMaxorderNum .custid

    递归cte

    查询管理员工
    --cte递归
    with eMpscte as
    (
         select firstname ,empid ,mgrid
         from HR.Employees
         where mgrid =2
         union all
         select e.firstname ,e.empid,e.mgrid
         from eMpscte  inner join  HR.Employees e
      on e.mgrid =eMpscte .empid   
    )
    select *
    from eMpscte

    3 视图 允许保存的 还有就是对查询进行抽象

    保存的只是查询语句,而不是数据

    在视图上做增删改
    很有问题
    当删除视图中的行时
    当这个视图只涉及到很简单的查询的时候(没有集合函数,没有连接,很简单的那种)会删除到基
    表中的数据
    插入也是如此
    会影响基表中的数据
    但是又不满足视图的
    查询条件
    为了防止冲突视图的查询语句末尾加上
    with check option

    --表函数
    不能单独使用,只能用在表达式中

    4表函数--单值函数,聚合函数

    第六章
    集合运算
    union
    则隐含的加了distinct关键字去掉两个表中重复的字段
    结果是一个真正的集合
     
    union all
    表示将两个表的查询结果相加,所有结果并不是一个真正的集合,而是一个多集

    intersect
    交集
    表示既属于A集合也属于B集合的集合
    但是里面默认有distinct去重

    要想都留着但是交集没有all关键字所以用以下方法


    with intersect_all
    as
    (
    select
    Row_number()
     over(partition by country,region,city
    order by (select 0)) as rownum,country,regiom
    city
    from hr.employees

    intrrsect

    Row_number()
     over(partition by country,region,city
    order by (select 0)) as rownum,country,regiom
    city
    from sales.customers;)
    select country,region,city
    from intersect_all

    用来代替生成intersect all
    表示返回没有生成标题列的行


    第七章
    1
    透视
    要解决透视
    先要标识转换涉及的元素:分组元素,拓展元素,聚合元素和聚合函数

    例子(为每个雇员返回一行数据,为为每个订单年份返回一列数据,计算每个雇员在每个订单年份处理过的订单数)

    select orderid ,empid,
    from


    select empid,[2007] as net2007,[2008] as net2008,[2009] as net2009
    from (select empid ,YEAR(orderdate)as orderdate
    from c) as s
    pivot (count(orderdate) for orderdate in([2007],[2008],[2009]))as o

    第一步;empid是分组元素,year(orderdate)是拓展元素,个数count是聚合函数,聚合元素不好找,因为count
    不会忽略null值,除非找到不是null的列,在这个例子中找到了year(orderdate)没有null的值
    因为求个数,所有尽量使用拓展元素使用的列
    其他列也可以,只有不为null就可以


    select 分组元素 ,要求显示的字段
    透视中没有使用的字段就默认分组了

    from(select 分组元素,拓展元素 ,聚合元素
    from 源表)as ..
    pivot (聚合函数(聚合元素)for 拓展元素 in(拓展元素字段))as..


    --另个方法
    select 分组元素,拓展元素,聚合函数(聚合元素),
    聚合元素(case when 拓展元素 = 。。then '聚合元素 ' end )as '',
    聚合元素(case when 拓展元素 = 。。then '聚合元素 ' end )as '',
    聚合元素(case when 拓展元素 = 。。then '聚合元素 ' end )as ''
    ......
    from 源表
    group by 分组元素,拓展元素
    2
    逆透视

    用unpivot
    select 提取的元素字段
    from 源表
    unpivot (聚合元素for 拓展元素in(源表的列表名))as

    3
    分组集
    group by
       grouping sets
    (
    (a,b),
    (a),
    (b),
    ()
    )

    --cube
    group by
       cube(a,b)
    --rollup 卷集 增加合计
    --函数 grouping,group_id

    八章
    修改
    update 表名
    set

    --一定要指定哪一行作为条件
    where

    delect from
    删除行
    九章

    特征
    原则性
    一致性
    隔离性
    持久性
    --隐式事务 ,数据库中每条语句中就是一个事务单位
    delect from HR.Employees where empid = 12;
    --显示事务 ,只有指定了显示事务才能保证事务一致性
    一般都是显示事务
    begin transaction
     
    delete from HR.Employees where =13;
    delete from HR.Employees where =14;

    结束事务的方式1-- roll back;回滚
    当执行到回滚时候删除的数据又回来了
    结束事务的方式2--commit 提交

    就是说在显示事务中要么两条都在,要不都不在

    隐式事务由系统管理,一条语句就是提交一次

    并发
    判断并发

    乐观并发

    有个时间戳的字段timestamp 但是并不是取时间的字段
    而是系统生成的一个二进制数字,每次变化都会变化

    悲观并发

    效率会降低但是可靠性会提高

    --加锁

    1 共享锁

    加个共享锁可以读,但是不可以改了

    2 独占锁

    3查看系统锁
    select
    from
     sys.dm_tran_locks;

    隔离级别

    1.读未提交,允许读取还没有提交的数据,读取不需要共享锁
     要显示设置
    set transaction isolation level read uncommitted
    设置后就可以读取未提交的数据
    不需要共享锁
    所有不能保证数据的一致性
    不一定是正确的
    ‘脏读’
     
    2.读提交,读取提交之后的数据,默认的隔离级别
    但是必须获取共享锁
    要吗是提交前的,要么是提交后的
    数据是正确的

    3
    可重复读
    repeatable read
    必须显示设置

    set transaction isolation level repeatable read;

    begin transaction
    会给查询数据加了共享锁
    (你的操作不会影响别人就是共享锁影响了别人的操作就是独占锁)
    但是前提都是在开始事务这个范围内

    4序列读 ,幻影读
    在事务中影响更深
    显示设置
    就是虽然可以防止这个行不受影响,但是不能给插入新的记录加锁,所有就要使用序列读
    set transaction isolation leve serializable

     -----快照级别
    提交之前读取的是原始数据
    提交之后读取的是提交后的数据
    这样两个会话不会阻塞
    以上的级别都会产生阻塞

    要提前启用数据库的快照级别
    alter database TSQLFundamentals2008
    set allow_snapshot_isolation on;

    显示设置快照级别 set transaction isolation level snapshot

    一般快照都会保存到临时数据库 tempdb中

    ------快照带提交级别

    要提前修改数据库提交级别


    alter database TSQLFundamentals2008
    set read_committed_snapshot on;

    显示设置读提交
    set transaction isolation leval read commited

    --死锁

    --基本原则解决死锁
    更新多个记录,按照相同的顺序进行更新


    10
    索引
    创建索引
    create index +名称 on + 表(字段)

    范式
    一级范式
    只要能把表存到数据库中肯定就满足一级范式
    二级范式
    解决部分依赖
    三级范式
    解决传递依赖


     

  • 相关阅读:
    关闭程序 提示 C#
    瀑布流判断加载分页条件
    移动端模板
    js 获取地址栏参数
    原生js倒计时和显示当前时间
    根据日期判断事件
    多个tab切换传参
    h5的api dom全屏展示
    git配置ssh
    git创建分支与合并分支
  • 原文地址:https://www.cnblogs.com/IBao/p/3129107.html
Copyright © 2011-2022 走看看