第一章
shanzm



第一章 检索记录

1.1检索所有行和列

问题:你有一张表,并且想查看表中的所有数据。

解决方案1:

    select * from EMP

解决方案2:

 select empno,ename,job,sal,mgr,hiredate comm,deptno from EMP

说明:

建议使用方案2,因为别人看你的代码的时候不一定知道你查询的表里面的列,所以还是写出查询的具体列更方便阅读。其次从优化的角度来说,尽量避免“ select * ” 的存在,使用具体的列代替*,避免返回多余的列。

【技巧】

  1. 查看SQL语句执行时间:
set statistics time on

select * from EMP
-- 注释:这里写你要测试执行时间的SQL语句

set statistics time off

运行结束之后,从消息栏,可以查看

  1. 查看SQL语句查询时对I/0的操作情况
set statistics io on

select * from EMP
-- 注释:这里写你要测试的SQL语句

set statistics io of

运行结束之后,从消息栏,可以查看:



1.2筛选行

问题:你有一张表,并且只想查看满足指定条件的行。

解决方案:
使用 WHERE 子句指明保留哪些行。使用 WHERE 子句来筛选出我们感兴趣的行。如果 WHERE 子句的表达式针对某一行的判定结果为真,那么就会返回该行的数据。

例如,下面的语句将查找部门编号为 10 的所有员工。

select * from EMP where DEPNO=10;

结果:



1.3查找满足多个查询条件的行

问题:你想返回满足多个查询条件的行。

解决方案:
使用带有 OR 和 AND 和圆括号()的 WHERE 子句。

例如,如果你想找出部门编号为 10 的所有员工、有奖金的所有员工以及部门编号是 20 且工资低于 2000 美元的所有员工。

【分析】也就是要找满足以下三种情况之一的员工(注意不是要求同时满足)

  • 部门编号=10;
  • 奖金不为Null(注意不是:奖金!=0,因为我们在数据库中,对无奖金的,填写为NULL);
  • 部门编号=20 & 工资<=2000;
select * from EMP
        where DEPTNO=10
                or COMM not NULL
                or SAL<=2000 and DEPTNO=20;

结果:


【补充】检索:20号部门中有奖金的员工和工资不高于2000的员工

SQL语句:

select * from EMP
        where (
                or comm is not null
                or sal <= 2000
              )
              and deptno=20;

【分析】以上SQL语句中的where字句的逻辑运算就是

(a|b)&c=(a&c)|(b&c)

where (comm is not null and deptno=20) or (sal <= 2000 and deptno=20)

结果:



1.4筛选列

问题:你有一张表,并且只想查看特定列的值。

解决方案:
select之后指定你想要查询的列。

例如,只查看员工的名字、部门编号和工资。

select ename,deptno,sal from EMP;

结果:



1.5创建列的别名

问题:你可能想要修改检索结果的列名,使其更具可读性且更易于理解。考虑下面这个查询,它返回的是每个员工的工资。

select ename,sal from emp

ename是什么吗?sal 指的是什么?显然这不方便阅读查询结果。

检索结果应该让人容易理解,所以我们可以在查询的时候自定义查询结果显示的列名(当然这不会改变数据库中表的列名)。

解决方案:
使用 AS 关键字创建别名,以 original_name AS new_name 的形式来修改检索结果的列名。

对于一些数据库而言, AS 不是必需的,但所有的数据库都支持这个关键字。

【注意】自定义的显示列名(别名),不允许有空格

SQL语句:

select
        ename as EmployeeName,
        sal as salary
from EMP
where deptno=30;

结果:



1.6 在where子句中引用别名列

问题:根据1.5中,已经为检索结果创建了有意义的列名
现在想要利用where子句来进行数据的过滤
但是你按照下面的SQL语句,则无法成功


select
        sal as salary ,
        comm as commission
from EMP

where salary<5000

为什么呢?

【注意】
where子句会比select子句先执行
from子句会比where子句先执行

所以你在上面的查询语句的时候,在执行where子句的时候,根本就还没有slaray。

解决方案:
法1.你在where子句中使用原始列名

select
        sal as salary ,
        comm as commission
from EMP

where sal<5000

法2.把查询包装为一个内嵌视图


select *
        from
        (
        select
                sal as salary
                comm as commission
        from EMP
        )
where salary<5000;



1.7 串联多列的值

问题:想要查询多列的值显示在一列上
比如说:

select ename,job
from EMP
where deptno=10

结果:

上面如愿查询到结果,但是想要显示为一列,如下:

怎么办呢?

解决方案:

select ename+' work as a ' +job as msg
from EMP
where deptno=10

结果:如上所希望。



1.8 在select语句里使用条件逻辑

问题:你想在 SELECT 语句中针对查询结果值执行 IF-ELSE 操作。
例如,你想生成类似这样的结果:
如果员工的工资少于 2000 美元,就返回 UNDERPAID ;
如果超过 4000 美元就返回OVERPAID ;
若介于两者之间则返回 OK 。
查询结果如下所示:

解决方案:
使用case语句

select ename ,sal ,
        case
                when sal>=4000 then 'OverPaid'
                when sal<=2000 then 'UnderPaid'
                else 'Ok'
        end as Status
from EMP

结果如上所愿!

【说明】
case语句格式如下:

case
        when 限制条件语句1 then '返回值1'
        when 限制条件语句2 then '返回值2'
        ...
        else '返回值'
end as 自定义列名 

【注意】
1.else子句是可选的,若没有它,对于不满足测试条件的行, case 表达式会返回 Null 。

2.case语句就是相当于一个列,所以自己给他定义了一个列名(在end后使用as关键字),同样因此用逗号和其他列名隔开。

3.注意返回值是使用单引号,SQL中字符串使用单引号引起



1.9 限定返回行数

问题:想要限定返回结果的行数,而且不在意排序。

例如:返回查询结果的前5行。

解决方案:使用 TOP 关键字限定返回行数。


select top 5 *
from EMP

结果是返回EMP表的前5行



1.10 随机返回若干行记录

问题:希望从表中获取特定数量的随机记录。

解决方案:利用order by newid()与top子句配合,实现在记录集中获取N条随机记录

select top 5 *
from EMP
order by newid()

结果是随机的在EMP表中选取5行。

【说明】
在MS SQL中函数newid()

  1. newid()函数产生一个全球唯一的标识,该标识是由网卡号、CPU时钟组成。从而保证该函数调用的返回值是唯一的。

  2. 该函数的返回值类型为uniqueidentifier类型,该类型必须与newid函数配合使用。

newid函数的用途:

正是由于uniqueidentifier的唯一性,我们通常用uniqueidentifier类型作为表的主键类型通过newid函数为该类型的字段新增或者更新值。

【举例】

create table test

(
        id uniqueidentifier primary key,

        name varchar(20)

)

插入新的数据:

insert into test values ( newid() , '小明' )



1.11 查找 Null 值

问题:你想查找特定列的值为 Null 的所有行。

注意:NULL是指无值(no value),它与字段包含 0、空字符串或仅仅包含空格不同。

解决方案:判断一个值是否为 Null ,必须使用 IS Null

select * from EMP
where comm is NULL

结果就是EMP表中comm列值是NULL的所有数据。

【说明】毫无疑问,查找特定列的值是非NULL的方式就是使用is not null



1.12 把 Null 值转换为实际值

问题:有一些行包含 Null 值,但是你想在查询的返回结果里将其替换为非 Null 值。

注意:只是把你查询的结果中的NULL换成其他的值,并不是修改数据库的表。

解决方案1:使用使用 coalesce() 函数将 Null 值替代为实际值。

例如:如果EMP表中的comm列的值是NULL,则返回0,若非NULL则返回comm值

select coalesce(comm,0)
from EMP

【说明】
coalesce 动词,合并的意思,读作[,koə'lɛs]

COALESCE(expression_1, expression_2, ...,expression_n)依次参考各参数表达式,遇到非null值即停止并返回该值。如果所有的表达式都是空值,最终将返回一个空值

解决方案2:使用case语句,但是没有coalesce()函数简洁

顺便说一句主流数据库都自带coalesce()函数。

select
        case
                when comm is not null then comm
                else 0
        end as comm
from EMP



1.13 查找匹配项

问题:你想返回匹配某个特定字符串或模式的行。

例如:你想从编号为 10 和 20 的两个部门中找到名字中含有字母 I 或职位以 ER 结尾的人。

解决方案:使用通配符%配合like 操作符

select ename, job
from emp
where deptno in (10,20)
      and (ename like '%I%' or job like '%ER')

【说明】

  1. 最常使用的通配符是百分号( % ),所有DBMS皆支持。在搜索串中, % 表示任何字符出现任意次数

  2. 通配符 % 看起来像是可以匹配任何东西,但有个例外,这就是 NULL 。子句 WHERE name LIKE '%' 不会匹配产品名称为 NULL 的行。

  3. MS SQL还有通配符[],此处不详述了。

【注意】通配符不利于SQL优化

用通配符时要记住的技巧。

  • 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
  • 在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的



02-09 18:51