好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SQLServer学习笔记系列1

一.前言 一直自己没有学习做笔记的习惯,所以为了加强自己对知识的深入理解,决定将学习笔记写下来,希望向各位大牛们学习交流!不当之处请斧正!在此感谢! 这边就先从学习Sqlserver写起,自己本身对数据库方面不擅长,所以决定对此从基础开始学习,大牛们

一.前言

一直自己没有学习做笔记的习惯,所以为了加强自己对知识的深入理解,决定将学习笔记写下来,希望向各位大牛们学习交流!不当之处请斧正!在此感谢!

这边就先从学习Sqlserver写起,自己本身对数据库方面不擅长,所以决定对此从基础开始学习,大牛们对此文可以忽略!首先以《Sqlserver2008技术内幕》

这本书作为学习的指 导,大家如果觉得这本书不错的话,可以去网上买一本,作为菜鸟的我,觉得这本书对于入门介绍的还是非常不错的。请戳

我:http://item.jd测试数据/10067484.html#none。

二.Sqlserver基础知识

(1)创建数据库

创建数据库有两种方式,手动创建和编写sql脚本创建,在这里我采用脚本的方式创建一个名称为TSQLFundamentals2008的数据库。 脚本如下:

   1   --  ------------------------------------------------------------------- 
   2   --   Microsoft SQL Server 2008 T-SQL Fundamentals 
   3   --
    4   --   Script that creates the sample database TSQLFundamentals2008 
   5   --
    6   --   Supported versions of SQL Server: 2005, 2008 
   7   --
    8   --   Based originally on the Northwind sample database 
   9   --   with changes in both schema and data to fit the book's needs 
  10   --
   11   --   Last updated: 20081202 
  12   --  ------------------------------------------------------------------- 
  13  
  14   --  ------------------------------------------------------------------- 
  15   --   Create Database 
  16   --  ------------------------------------------------------------------- 
  17  
  18   USE   master;
   19  
  20   --   Drop database 
  21   IF   DB_ID ( '  TSQLFundamentals2008  ' )  IS   NOT   NULL   DROP   DATABASE   TSQLFundamentals2008;
   22  
  23   --   If database could not be created due to open connections, abort 
  24   IF   @@ERROR   =   3702  
  25      RAISERROR ( '  Database cannot be dropped because there are still open connections.  ' ,  127 ,  127 )  WITH  NOWAIT,  LOG  ;
   26  
  27   --   Create database 
  28   CREATE   DATABASE   TSQLFundamentals2008;
   29   GO 
  30  
  31   USE   TSQLFundamentals2008;
   32   GO 
  33  
  34   --  ------------------------------------------------------------------- 
  35   --   Create Schemas 
  36   --  ------------------------------------------------------------------- 
  37  
  38   CREATE   SCHEMA  HR  AUTHORIZATION   dbo;
   39   GO 
  40   CREATE   SCHEMA  Production  AUTHORIZATION   dbo;
   41   GO 
  42   CREATE   SCHEMA  Sales  AUTHORIZATION   dbo;
   43   GO 
  44  
  45   --  ------------------------------------------------------------------- 
  46   --   Create Tables 
  47   --  ------------------------------------------------------------------- 
  48  
  49   --   Create table HR.Employees 
  50   CREATE   TABLE   HR.Employees
   51   (
   52    empid            INT            NOT   NULL   IDENTITY  ,
   53    lastname         NVARCHAR ( 20 )  NOT   NULL  ,
   54    firstname        NVARCHAR ( 10 )  NOT   NULL  ,
   55    title            NVARCHAR ( 30 )  NOT   NULL  ,
   56    titleofcourtesy  NVARCHAR ( 25 )  NOT   NULL  ,
   57    birthdate        DATETIME       NOT   NULL  ,
   58    hiredate         DATETIME       NOT   NULL  ,
   59    address          NVARCHAR ( 60 )  NOT   NULL  ,
   60    city             NVARCHAR ( 15 )  NOT   NULL  ,
   61    region           NVARCHAR ( 15 )  NULL  ,
   62    postalcode       NVARCHAR ( 10 )  NULL  ,
   63    country          NVARCHAR ( 15 )  NOT   NULL  ,
   64    phone            NVARCHAR ( 24 )  NOT   NULL  ,
   65    mgrid            INT            NULL  ,
   66     CONSTRAINT  PK_Employees  PRIMARY   KEY  (empid),
   67     CONSTRAINT  FK_Employees_Employees  FOREIGN   KEY  (mgrid)
   68       REFERENCES   HR.Employees(empid),
   69     CONSTRAINT  CHK_birthdate  CHECK (birthdate     CURRENT_TIMESTAMP  )
   70   );
   71  
  72   CREATE   NONCLUSTERED   INDEX  idx_nc_lastname  ON   HR.Employees(lastname);
   73   CREATE   NONCLUSTERED   INDEX  idx_nc_postalcode  ON   HR.Employees(postalcode);
   74  
  75   --   Create table Production.Suppliers 
  76   CREATE   TABLE   Production.Suppliers
   77   (
   78    supplierid    INT            NOT   NULL   IDENTITY  ,
   79    companyname   NVARCHAR ( 40 )  NOT   NULL  ,
   80    contactname   NVARCHAR ( 30 )  NOT   NULL  ,
   81    contacttitle  NVARCHAR ( 30 )  NOT   NULL  ,
   82    address       NVARCHAR ( 60 )  NOT   NULL  ,
   83    city          NVARCHAR ( 15 )  NOT   NULL  ,
   84    region        NVARCHAR ( 15 )  NULL  ,
   85    postalcode    NVARCHAR ( 10 )  NULL  ,
   86    country       NVARCHAR ( 15 )  NOT   NULL  ,
   87    phone         NVARCHAR ( 24 )  NOT   NULL  ,
   88    fax           NVARCHAR ( 24 )  NULL  ,
   89     CONSTRAINT  PK_Suppliers  PRIMARY   KEY  (supplierid)
   90   );
   91  
  92   CREATE   NONCLUSTERED   INDEX  idx_nc_companyname  ON   Production.Suppliers(companyname);
   93   CREATE   NONCLUSTERED   INDEX  idx_nc_postalcode   ON   Production.Suppliers(postalcode);
   94  
  95   --   Create table Production.Categories 
  96   CREATE   TABLE   Production.Categories
   97   (
   98    categoryid    INT             NOT   NULL   IDENTITY  ,
   99    categoryname  NVARCHAR ( 15 )   NOT   NULL  ,
  100    description   NVARCHAR ( 200 )  NOT   NULL  ,
  101     CONSTRAINT  PK_Categories  PRIMARY   KEY  (categoryid)
  102   );
  103  
 104   CREATE   INDEX  categoryname  ON   Production.Categories(categoryname);
  105  
 106   --   Create table Production.Products 
 107   CREATE   TABLE   Production.Products
  108   (
  109    productid     INT            NOT   NULL   IDENTITY  ,
  110    productname   NVARCHAR ( 40 )  NOT   NULL  ,
  111    supplierid    INT            NOT   NULL  ,
  112    categoryid    INT            NOT   NULL  ,
  113    unitprice     MONEY          NOT   NULL 
 114       CONSTRAINT  DFT_Products_unitprice  DEFAULT ( 0  ),
  115    discontinued  BIT            NOT   NULL  
 116       CONSTRAINT  DFT_Products_discontinued  DEFAULT ( 0  ),
  117     CONSTRAINT  PK_Products  PRIMARY   KEY  (productid),
  118     CONSTRAINT  FK_Products_Categories  FOREIGN   KEY  (categoryid)
  119       REFERENCES   Production.Categories(categoryid),
  120     CONSTRAINT  FK_Products_Suppliers  FOREIGN   KEY  (supplierid)
  121       REFERENCES   Production.Suppliers(supplierid),
  122     CONSTRAINT  CHK_Products_unitprice  CHECK (unitprice  >=   0  )
  123   );
  124  
 125   CREATE   NONCLUSTERED   INDEX  idx_nc_categoryid  ON   Production.Products(categoryid);
  126   CREATE   NONCLUSTERED   INDEX  idx_nc_productname  ON   Production.Products(productname);
  127   CREATE   NONCLUSTERED   INDEX  idx_nc_supplierid   ON   Production.Products(supplierid);
  128  
 129   --   Create table Sales.Customers 
 130   CREATE   TABLE   Sales.Customers
  131   (
  132    custid        INT            NOT   NULL   IDENTITY  ,
  133    companyname   NVARCHAR ( 40 )  NOT   NULL  ,
  134    contactname   NVARCHAR ( 30 )  NOT   NULL  ,
  135    contacttitle  NVARCHAR ( 30 )  NOT   NULL  ,
  136    address       NVARCHAR ( 60 )  NOT   NULL  ,
  137    city          NVARCHAR ( 15 )  NOT   NULL  ,
  138    region        NVARCHAR ( 15 )  NULL  ,
  139    postalcode    NVARCHAR ( 10 )  NULL  ,
  140    country       NVARCHAR ( 15 )  NOT   NULL  ,
  141    phone         NVARCHAR ( 24 )  NOT   NULL  ,
  142    fax           NVARCHAR ( 24 )  NULL  ,
  143     CONSTRAINT  PK_Customers  PRIMARY   KEY  (custid)
  144   );
  145  
 146   CREATE   NONCLUSTERED   INDEX  idx_nc_city  ON   Sales.Customers(city);
  147   CREATE   NONCLUSTERED   INDEX  idx_nc_companyname  ON   Sales.Customers(companyname);
  148   CREATE   NONCLUSTERED   INDEX  idx_nc_postalcode   ON   Sales.Customers(postalcode);
  149   CREATE   NONCLUSTERED   INDEX  idx_nc_region       ON   Sales.Customers(region);
  150  
 151   --   Create table Sales.Shippers 
 152   CREATE   TABLE   Sales.Shippers
  153   (
  154    shipperid    INT            NOT   NULL   IDENTITY  ,
  155    companyname  NVARCHAR ( 40 )  NOT   NULL  ,
  156    phone        NVARCHAR ( 24 )  NOT   NULL  ,
  157     CONSTRAINT  PK_Shippers  PRIMARY   KEY  (shipperid)
  158   );
  159  
 160   --   Create table Sales.Orders 
 161   CREATE   TABLE   Sales.Orders
  162   (
  163    orderid         INT            NOT   NULL   IDENTITY  ,
  164    custid          INT            NULL  ,
  165    empid           INT            NOT   NULL  ,
  166    orderdate       DATETIME       NOT   NULL  ,
  167    requireddate    DATETIME       NOT   NULL  ,
  168    shippeddate     DATETIME       NULL  ,
  169    shipperid       INT            NOT   NULL  ,
  170    freight         MONEY          NOT   NULL 
 171       CONSTRAINT  DFT_Orders_freight  DEFAULT ( 0  ),
  172    shipname        NVARCHAR ( 40 )  NOT   NULL  ,
  173    shipaddress     NVARCHAR ( 60 )  NOT   NULL  ,
  174    shipcity        NVARCHAR ( 15 )  NOT   NULL  ,
  175    shipregion      NVARCHAR ( 15 )  NULL  ,
  176    shippostalcode  NVARCHAR ( 10 )  NULL  ,
  177    shipcountry     NVARCHAR ( 15 )  NOT   NULL  ,
  178     CONSTRAINT  PK_Orders  PRIMARY   KEY  (orderid),
  179     CONSTRAINT  FK_Orders_Customers  FOREIGN   KEY  (custid)
  180       REFERENCES   Sales.Customers(custid),
  181     CONSTRAINT  FK_Orders_Employees  FOREIGN   KEY  (empid)
  182       REFERENCES   HR.Employees(empid),
  183     CONSTRAINT  FK_Orders_Shippers  FOREIGN   KEY  (shipperid)
  184       REFERENCES   Sales.Shippers(shipperid)
  185   );
  186  
 187   CREATE   NONCLUSTERED   INDEX  idx_nc_custid  ON   Sales.Orders(custid);
  188   CREATE   NONCLUSTERED   INDEX  idx_nc_empid           ON   Sales.Orders(empid);
  189   CREATE   NONCLUSTERED   INDEX  idx_nc_shipperid       ON   Sales.Orders(shipperid);
  190   CREATE   NONCLUSTERED   INDEX  idx_nc_orderdate       ON   Sales.Orders(orderdate);
  191   CREATE   NONCLUSTERED   INDEX  idx_nc_shippeddate     ON   Sales.Orders(shippeddate);
  192   CREATE   NONCLUSTERED   INDEX  idx_nc_shippostalcode  ON   Sales.Orders(shippostalcode);
  193  
 194   --   Create table Sales.OrderDetails 
 195   CREATE   TABLE   Sales.OrderDetails
  196   (
  197    orderid    INT             NOT   NULL  ,
  198    productid  INT             NOT   NULL  ,
  199    unitprice  MONEY           NOT   NULL 
 200       CONSTRAINT  DFT_OrderDetails_unitprice  DEFAULT ( 0  ),
  201    qty        SMALLINT        NOT   NULL 
 202       CONSTRAINT  DFT_OrderDetails_qty  DEFAULT ( 1  ),
  203    discount  NUMERIC( 4 ,  3 )  NOT   NULL 
 204       CONSTRAINT  DFT_OrderDetails_discount  DEFAULT ( 0  ),
  205     CONSTRAINT  PK_OrderDetails  PRIMARY   KEY  (orderid, productid),
  206     CONSTRAINT  FK_OrderDetails_Orders  FOREIGN   KEY  (orderid)
  207       REFERENCES   Sales.Orders(orderid),
  208     CONSTRAINT  FK_OrderDetails_Products  FOREIGN   KEY  (productid)
  209       REFERENCES   Production.Products(productid),
  210     CONSTRAINT  CHK_discount   CHECK  (discount  BETWEEN   0   AND   1  ),
  211     CONSTRAINT  CHK_qty   CHECK  (qty  >   0  ),
  212     CONSTRAINT  CHK_unitprice  CHECK  (unitprice  >=   0  )
  213   )
  214  
 215   CREATE   NONCLUSTERED   INDEX  idx_nc_orderid  ON   Sales.OrderDetails(orderid);
  216   CREATE   NONCLUSTERED   INDEX  idx_nc_productid  ON   Sales.OrderDetails(productid);
  217   GO  

View Code

同时往数据库表插入一些数据,用户后续对数据库的sql的练习。在这里有需要的可以下载相应的脚本进行数据库的初始化。我放到百度云上面,请戳

我:http://yun.baidu测试数据/share/link?shareid=3635107613&uk=2971209779,提供了《Sqlserver2008技术内幕》这本书的电子版和脚本。

(2)在这里对TSQLFundamentals2008数据各个表进行表说明一下:

数据库表界面如下:

HR.Employees

雇员表,存放员工的一些基本信息。

Production.Products

产品信息表

Production.Suppliers

供应商表

Production.Customers

顾客信息表

Production.Categories

产品类别表

Sales.OrderDetails

订单详情表

Sales.Orders

订单表

Sales.Shippers

货运公司表

三.Sqlserver一些基本命令:

查询数据库是否存在:

if DB_ID("testDB")is not null;

检查表是否存在:

if OBJECT_ID([textDB],[U]) is not null ;其中U代表用户表

创建数据库:

create database+数据名

删除数据库:

drop database 数据库名 --删除数据库的

drop table 表名--删除表的

delete from 表名 where 条件 --删除数据的

查询语句:

use 数据库名称 --修改的数据库

select*from +表名称 --要查询的表

select某某,某某,某某 from 表名称 where 条件 --带条件查询的数据

插入数据:

insert into 表名称 (条件)values (相对应的值)

四.单表查询

(1)分组--对于分组查询,select字句会有限制,需要查询字段要出现在group by 子句中,同时分组以后,可以对分组情况进行统计。

查询雇员表,根据雇员所在国家分组,统计每组的人数情况:

 1   select  country, count ( * )  as  N '  人数  ' 
 2   from   hr.Employees
  3   group   by  country 

当要查询的字段不包含在group by子句中,则会报相应的错误,所以此时要注意出现在select 后面的查询字段进行分组后,也同时需要出现在group by后面。

(2)在这里提示一下: 查询条件不要使用计算列,下面谈谈具体原因:

例如:查询雇员表里面雇员出生为1973年的所有雇员信息,可以这样编写sql语句:

 1   select   YEAR (birthdate),firstname,lastname  from   HR.Employees
  2   where   YEAR (birthdate) =  '  1973  '  

可以看到查询结果将1973年的雇员信息查出来了,但是大家可以思考一下,上面的sql语句在查询的时候,首先是要讲birthdate进行取出年度的计算,

Year(birthdate),其中 Year为sql的内置函数,可以用于对字符串日期进行取出年份的计算。 同时我们还可以采用下面的sql语句进行查询:

通过sql执行计划可以看出来,查询条件带计算列走的是索引扫描,而where子句后面采用查找范围限制,则走的是索查找。对比两个查询显然绝大部分情况下

走索引查找的查询性能 要高于走索引扫描,特别是查询的数据库不是非常大的情况下,索引查找的消耗时间要远远少于索引扫描的时间。所以在查询条件中尽

量避免计算条件。

(3)说说sqlserver中的null,null在数据库中表示不存在,与C#中的null不同,不表示空引用,没有对象, NULL的运算规则:有null的任何运算都是null。

is [not] null: 只能用做条件判断表达式,是否是null?是 条件为true,不是 条件为false。

isnull():函数,如果第一个参数是null,则用第二个参数的值替换第一个参数的值作为函数的返回值。记住:第二个参数的类型必须和第一个兼容。

nullif():函数,如果两个参数值相等、有一个参数是null、或两个参数是null,函数返回值是null;否则返回第一个参数的值。

(4)top用法:意在取出表中满足条件的前多少位。top 10---前10位

说到top,突然想到了面试题中经常出现的查询某表中的前30—40条记录,注意id可能不连续。利用top可以这样写:

 1   select   top   10   *   from  A  where   ID
  2   not   in ( select   top   30  ID  from  A   order   by  ID  asc  )
  3   order   by  ID  asc  

同时也可以采用如下写法,只不过可读性比较差:

 1   select   top   10   *  fron A  where  ID > 
 2  ( select   Max (ID)  from  ( select   top   30  ID  from  A  order   by  ID) as   t)
  3   order   by  ID  asc  

当然既然有范围in存在,就可以用exist实现:

 1   select   top   10   *   from   A a1 
  2   WHERE   NOT   EXISTS  
 3  ( SELECT   *   from  
 4  ( SELECT   TOP   30   *   FROM  A  ORDER   BY  id  asc  ) a2
  5   WHERE  a2.id  =  a1.id 
  6  ) 

但是目前需要考虑到---- 相关子查询:主查询每遍历一条记录时,都要针对主查询的值执行子查询,所以效率比较低。

下面介绍一下top与percent联合使用,percent表示所占的百分比:例如查询雇员表里面,前面百分之二十的雇员的信息,可以写sql,查询 结果为两人。

  1   select   top ( 20 )  percent   *   from  hr.employees    

我们在查询一下hr.employees(雇员表),同时查询一下雇员表里面总共有多少人,查出结果显示有9人。

 1   select   count ( * )  as  N '  总人数  '   from  hr.employees 

可以看出,9个人按百分之二十取整数了,所以查出来的显示有两个人。

(5)with ties附加属性:

当我们查询订单表时,查询sql:

 1   select   orderid,orderdate
  2   from  sales.orders  order   by  orderdate   desc  

加入我们查询前五个订单信息时候,加入top 5

 1   select   top   5   orderid,orderdate
  2   from  sales.orders  order   by  orderdate   desc  

查询结果如图:

对比没有加top 5,查询结果截取了前五条订单信息,但是有时候我们需要将与最后一条订单日期相同的一起取出来,此时就需要采用附加属性with ties。

(6)over开窗函数:

上面讲到要用count聚合函数,在需要分组求和。但采用over 则可以同样实现基于什么的求和。省去group by。

 1   select  firstname,lastname , count ( * )  over ()   as  N '  总人数  ' 
 2   from  hr.employees 

其中over(),括号里面可以附加条件,基于什么进行汇总。不添加,则表示对所有的记录进行汇总。例如求每位顾客所消费的订单总额,可以这样写:

 1   select  orderid,custid, sum (val)  over  (partition  by  custid)  as  N '  顾客消费总额  '  ,
  2   sum (val)  over ()  as  N '  订单总额  '   from  sales.ordervalues 

五.排名函数

(1)row_number,行号,一般与over联合使用。over基于什么排名。

 1   select  row_number()  over ( order   by  lastname)  as  N '  行号  '  , lastname,firstname
  2   from  hr.employees 

(2)rank ,排名,真正意义上的排名,例如:

 1   select  country,row_number()  over ( order   by  country)  as  N '  rank排名  '  , lastname,firstname
  2   from  hr.employees 

可以看出,根据country排名,确实排出来啦,但是发现前四位同为UK,按理来说使部分先后顺序的,所以在此可以用rank来操作。

 1   select  country,rank()  over ( order   by  country)  as  N '  rank排名  '  , lastname,firstname
  2   from  hr.employees 

可以看出来,使用rank以后,country同为UK的并列第一,类似于学生考试成绩排名并列第一的情况。

(3)dense_rank,密集排名

通过上面rank排名以后,存在并列第一的情况,但是country为USA的应该为第二,所以就出现了使用密集排名dense_rank进行排名。

 1   select  country,dense_rank()  over ( order   by  country)  as  N '  dense_rank排名  '  , lastname,firstname
  2   from  hr.employees 

可以看出采用dense_rank以后,就满足了某一条件下,同属一个名次的需求。

(4)分组ntile。按某一条件进行分组。

 1   select  country,ntile( 3 )  over  ( order   by  country)  as  N '  ntile分组  ' ,dense_rank()  over ( order   by  country)  as  N '  dense_rank排名  '  , lastname,firstname
  2   from   hr.employees
  3   order   by  country 

有时候为了在某一个范围内进行排序,比如:

 1   select  lastname,firstname,country,row_number()  over (  order   by  country)  as  N '  排名  ' 
 2   from  hr.employees 

为了实现根据在country范围内排序,即country为Uk的为一组进行排序,country为USA的为一组进行排序。可以这样写:

 1   select  lastname,firstname,country,row_number()  over ( partition  by  country  order   by  country)  as  N '  排名  ' 
 2   from  hr.employees 

希望各位大牛给出指导,不当之处虚心接受学习!谢谢!

查看更多关于SQLServer学习笔记系列1的详细内容...

  阅读:39次