SQl查询基础

SQL语言是一门简单易学却又功能强大的语言,他让你快速上手并写出比较复杂的查询语句,但对于大多数开发者来书,使用SQL查询数据库并无一个抽象的过程和一个合理的步骤,这极可能会是在写一些特定的查询语句来解决特定问题是被卡住。本系列文章主要讲述SQL查询时一些基本的理论,以及写查询语句的抽象思路。html

这是转自http://www.cnblogs.com/CareySon/archive/2010/04/05/1704928.html的一篇文章。算法

但愿在看文章的同时我也看以对SQL查询有更多的了解和学习。sql

SQL查询简介:数据库

SQL语言起源于1970年E.J.Codd发表的关系数据库理论,因此SQL是为关系数据库服务的。数据库设计

而对于SQL查询,是指从数据库中取得数据的子集函数

精确查询的前置条件:性能

对于正确取得所须要的数据子集,除了须要思路正确并将思路正确转变为对应的SQL查询语句以外,还有很重要的一点是须要数据库有良好的设计,这里的良好设计我所指的是数据库设计符合业务逻辑并至少实现第三范式。对于实现第三范式,这只是我的观点。学习

两种方式,同一结果:优化

在SQL中,取得相同的数据子集能够用不一样的思路或不一样的SQL语句,由于SQL源于关系数据库理论,而关系数据库理论又源于数学,思考如何构建查询语句时,均可以抽象为两种方法:加密

一、关系代数法,关系代数法的思路是对数据库进行分布操做,最后取得想要的结果。

好比:

Select Name,Department,Age
From Employee
where Age>20

关系代数的思路描述上面的语句为:对标Employee表进行投影(选择列)操做,而后对结果进行筛选,只取得年龄大于20 的结果。

二、关系演算法,相比较于关系代数而言,关系演算法更多的是取得数据所知足的条件,上面SQL能够用关系演算法描述为u:我想获得全部年龄大于20岁的员工的姓名、部门和年龄。

为何须要两种方法

对于简单的查询语句来讲,上面两种方法都不须要.用脚就能够想出来了。问题在于不少查询语句都会很是复杂。对于关系演算法来讲更多的是关注的是所取出信息所知足的条件,而对于关系代数法来讲,更多关注的是如何取出特定的信息.简单的说,关系演算法表示的是”what”,而关系代数法表达的是”how”.SQL语句中所透漏的思路,有些时候是关系代数法,有些时候是关系演算法,还有些是两种思路的混合.

     对于某些查询状况,关系代数法可能会更简单,而对于另一些状况,关系演算法则会显得更直接.还有一些状况.咱们须要混合两种思路。因此这两种思惟方式在写SQL查询时都是必须的.

 

单表查询:

单表查询是全部查询的中间状态,既是多个表的复杂查询在最终进行这种链接后都可以被抽象成单表查询,因此最早从单表查询开始:

选择列的子集

       根据上面数据子集的说法,选择列是经过在select语句后面添加所要选择的列名实现的:

     好比下面数据库中经过在select后面选择相应的列名实现选择列的子集.

    5

   相应sql语句以下:

SELECT [Name]
      ,[GroupName]
  FROM [AdventureWorks].[HumanResources].[Department]

 

选择行的子集

      选择行的子集是在Sql语句的where子句后面加上相应的限制条件,当where子句后面的表达式为“真”时,也就是知足所谓的“条件”时,相应的行的子集被返回。

      where子句后面的运算符分为两类,分别是比较运算符逻辑运算符.

     比较运算符是将两个相同类型的数据进行比较,进而返回布尔类型(bool)的运算符,在SQL中,比较运算符一共有六种,分别为等于(=),小于(<),大于(>),小于或等于(<=),大于或等于(>=)以及不等于(<>),其中小于或等于和大于或等于能够当作是比较运算符和逻辑运算符的结合体。

      而逻辑运算符是将两个布尔类型进行链接,并返回一个新的布尔类型的运算符,在SQL中,逻辑运算符一般是将比较运算符返回的布尔类型相链接以最终肯定where子句后面知足条件的真假。逻辑运算符一种有三种,与(AND),或(OR),非(NOT).

  

      6

   好比上面,我想选择第二条和第六条,为了说明比较运算符和逻辑运算符,可使用以下Sql语句:

SELECT [Name]
      ,[GroupName]
  FROM [AdventureWorks].[HumanResources].[Department]
  WHERE DepartmentID>1 and DepartmentID<3 or DepartmentID>5 and DepartmentID<7

  由此咱们能够看出,这几种运算符是有优先级的,优先级由大到小排列是比较运算符>于(And)>非(Or)

   固然,运算符也能够经过小括号来改变优先级,对于上面那个表

   8

   对于不加括号时:

SELECT *
  FROM [AdventureWorks].[HumanResources].[Department]
  WHERE DepartmentID>=1 and DepartmentID<=3 and DepartmentID>=5 or DepartmentID<=7

   9

  加了括号改变运算顺序后:

SELECT *
  FROM [AdventureWorks].[HumanResources].[Department]
  WHERE DepartmentID>=1 and DepartmentID<=3 and (DepartmentID>=5 or DepartmentID<=7)

 10

 

很特别的NULL

    假如在一个用户注册的表中,一些选填信息并不须要用户必须填写,则在数据库中保存为null,这些null值在利用上面where子句后的运算符时,有可能形成数据丢失,好比一个选填信息是性别(Gender),假设下面两条条件子句:

where Gender="M"

 

where NOT (Gender="M")

   因为null值的存在,这两条语句返回的数据行加起来并非整个表中的全部数据。因此,当将null值考虑在内时,where后面的条件子句拥有可能的值从真和假,增长为真,假,以及未知(null)。这些是咱们在现实世界中想一些问题的时候可能的答案--真的,假的,我不知道。

    因此咱们如何在这种状况下不丢失数据呢,对于上面的例子来讲,如何才能让整个表的数据不被丢失呢,这里必须将除了“真”,“假”之外的“未知”这个选项包含在内,SQL提供了IS NULL来代表未知这个选项:

where Gender IS NULL

   将上面语句加入进去,则不会再丢失数据。

 

排序结果

      上面的那些方法都是关于取出数据,而下面是关于将取出的子集进行排序。SQL经过Order by子句来进行排序,Order by子句是Sql查询语句的最后一个子句,也就是说Order by子句以后不能再加任何的子句了。

      Order By子句分为升序(ASC)和降序(DESC),若是不指定升序或者降序,则默认为升序(由小到大),而Order by是根据排序依据的数据类型决定,分别为3种数据类型能够进行排序:

  1. 字符
  2. 数字
  3. 时间日期

     字符按照字母表进行排序,数字根据数字大小排序,时间日期根据时间的前后进行排序。

     

其它一些有关的

  视图

       视图能够看做是一个保存的虚拟表,也能够简单看作是保存的一个查询语句。视图的好处是视图能够根据视图所查询表的内容的改变而改变,打个比方来理解这句话是:

    12

     使用视图的优势是能够对查询进行加密以及便于管理,听说还能够优化性能(我不承认这点).

 

防止重复

       有时候咱们对于取出的数据子集不想重复,好比你想知道一些特定的员工一共属于几个部门

SELECT [EmployeeID]
      ,[DepartmentID]
  FROM [AdventureWorks].[HumanResources].[EmployeeDepartmentHistory]

15

   这样的结果是没有意义的,SQL提供了Distinct关键字来实现这点:

SELECT distinct DepartmentID
  FROM [AdventureWorks].[HumanResources].[EmployeeDepartmentHistory]

16

 

 

聚合函数

     所谓聚合函数,是为了一些特定目的,将同一列多个值聚合为一个,好比我想知道一群人中最大年龄是多少能够利用MAX(Age),好比我想知道一个班级平均测验成绩是多少能够用AVG(Result)……

相关文章
相关标签/搜索