SQL学习笔记(三) SELECT查询入门

本文为《SQL学习指南》一书的学习笔记,供自己记录查找使用。如有侵权可私信删除.

今日文章包括:chap 3 SELECT查询入门;chap 4 过滤;chap 5 多表连接。

目录

一、select子句

1.列的别名(标签)

2.去除重复值

二、FROM子句

1.虚拟表(视图)

2.两表连接

内连接 INNER JOIN

外连接  OUTER JOIN

3.多表连接(第五章,未完待续)

 将子查询的结果作为查询表

 连续两次使用同一个表

4.自连接

 5.相等连接与不等连接

6.连接条件与过滤条件

三、WHERE子句

四、GROUP BY 和HAVING子句

五、ORDER BY子句

今日命令小结:


一、select子句

在select子句中可以使用列名、字符、表达式和内建函数

SELECT emp_id,

    -> 'ACTIVE',

    -> emp_id * 3.14159,

    -> UPPER(lname)

    -> FROM employee;

如果只是需要执行一个内建函数 or 对表达式求值,则不需要调用任何表,可以不使用FROM子句。例如:

SELECT VERSION(),

    -> USER(),

    -> DATABASE();

1.列的别名(标签)

select column_1 as label_1,column_2 as label_2,… ,as可以省略,即

select column_1 label_1,column_2 label_2,…

SELECT emp_id,

    -> 'ACTIVE' status,

    -> emp_id * 3.14159 empid_x_pi,

    -> UPPER(lname) last_name_upper

    -> FROM employee;

2.去除重复值

使用DISTINCT关键字  (系统默认不去除:ALL)

二、FROM子句

定义所查询的表以及他们的连接方式。有三种表:

  • 永久表  (create table语句所创建)
  • 临时表  (子查询所返回的表)
  • 虚拟表  (create view 所创建的视图)

1.虚拟表(视图)

        视图又叫虚拟表,表现得象一个表但实际上并不具有任何数据,它是存储在数据字典中的查询。通常用于对用户隐藏列、简化数据库设计等场景。

示例:

CREATE VIEW employee_vw AS

    -> SELECT emp_id,fname,lname,

    -> YEAR(start_date) start_year

    -> FROM employee;

创建了视图之后并没有产生或存储任何数据,只是简单保留了这个查询以供后续使用。比如现在可以查询这个视图:

SELECT emp_id,start_year

    -> FROM employee_vw;

2.两表连接

可以使用多种JOIN语句对表进行连接。

内连接 INNER JOIN

是默认的连接方式。如果连接两表的列中的某一条数据在其中一个表中不存在,内连接所得的新表将不包含这条数据。这是默认连接方式,但是最好还是指明连接类型。例:

SELECT e.fname,e.lname,d.name

    -> FROM employee e INNER JOIN department d

    -> ON e.dept_id=d.dept_id;

 如果连接两个表的列名一样,可以将ON子句换成USING子句。不过,它只能在某些特殊情况下起到简化语法的作用,建议一直使用ON保持良好的编程习惯。

SELECT e.fname,e.lname,d.name

    -> FROM employee e INNER JOIN department d

    -> USING (dept_id);

外连接  OUTER JOIN

除去那些在两个表中都存在的值外,如果某个值只在一个表中出现,也将其加入新连接的表中。

3.多表连接(第五章,未完待续)

在多表连接中,没有前后顺序之分。如果想要按某种顺序连接,可在SELECT 后加上STRAIGHT_JOIN关键字使它后面跟的第一个表成为驱动表。

SELECT a.account_id,c.fed_id,e.fname,e.lname

    -> FROM employee e INNER JOIN account a

    -> ON e.emp_id = a.open_emp_id

    -> INNER JOIN customer c

    -> ON a.cust_id = c.cust_id

    -> WHERE c.cust_type_cd = 'B';

 将子查询的结果作为查询表

SELECT a.account_id ,a.cust_id,a.open_date,a.product_cd
    -> FROM account a INNER JOIN
    ->  (SELECT emp_id,assigned_branch_id
    -> FROM employee
    -> WHERE start_date < '2007-01-01'
    -> AND (title = 'Teller' OR title = 'Head Teller')) e
    -> ON a.open_emp_id =e.emp_id
    -> INNER JOIN
    -> (SELECT branch_id
    -> FROM branch
    -> WHERE name = 'Woburn Branch') b
    -> ON e.assigned_branch_id = b.branch_id;

 连续两次使用同一个表

举个例子:表account与表employee要通过柜员编号id进行连接,一个柜员一条数据。而account表要与branch连接一次,来提取这个柜员的开户支行;employee也要与branch连接一次,来提取这个柜员工作所在的支行。为了服务器能将两次连接引用区分开来,也为了让我们不混淆,我们可以两次连接branch表并分别为其定义不同的别名,如下所示:

SELECT a.account_id ,e.emp_id,b_a.name open_branch,b_e.name emp_branch
    -> FROM account a INNER JOIN branch b_a /*第一次起别名,与a连接*/
    -> ON a.open_branch_id = b_a.branch_id
    -> INNER JOIN employee e
    -> ON a.open_emp_id = e.emp_id
    -> INNER JOIN branch b_e
    -> ON e.assigned_branch_id = b_e.branch_id
    -> WHERE a.product_cd = 'CHK';

4.自连接

举例说明:employee表包含了一个指向自己的外键superior_emp_id(表示这个职员的主管领导),也就是说这一列(外键)是指向一个主键的,而这个主键就在自身这张表里,即为emp_id。这样如果我们想要同时列出职工和主管的姓名,只要为表定义不同的别名即可。如下示例。

这是表的情况,有助于理解题意:

自连接代码如下,很好理解: 

SELECT CONCAT(e.fname," ",e.lname) employee,
    -> CONCAT(s.fname," ",s.lname) superior
    -> FROM employee e INNER JOIN employee s
    -> ON s.superior_emp_id = e.emp_id;

查询结果如下:

 注意:employee表中共有18行,但这个查询只返回了17行,因为Micheal Smith是银行总经理,他自己已经没有主管了,因此在这一行上的连接失败了。为了在结果集中包含Smith,则需要使用外连接,在后文中将对这一内容进行介绍。

 (复习:①外键不要求数值各异:可以一个不同的条目对应于同一个主键,比如一个领导(外键表示的id为同一个数字,这个数字在主键列存在且仅存在一次)对应于好几个职员(好几个外键连接同一个主键,即外键列这个数字出现好几次);②定义外键约束时使用CONSTRAINT ... FOREIGN KEY (...) 语句即可);③使用CONCAT函数拼接字符串。)     

 5.相等连接与不等连接

很明显,不等连接时常常会产生笛卡尔积。如下例:

SELECT e.emp_id,e.start_date FROM employee e INNER JOIN product p
    -> ON e.start_date >= p.date_offered;

结果是18*8的表(employee 18行,product 8行,没有过滤条件,全部符合连接条件,于是直接产生144行的新表。)

 也可以产生不等的自连接:比如我们想让柜员们两两下一盘棋,把对弈名单列出来:

SELECT e1.emp_id A,concat(e1.fname," ",e1.lname," VS ",e2.fname," ",e2.lname) VERSUS ,e2.emp_id B
FROM employee e1 INNER JOIN employee e2
ON e1.emp_id < e2.emp_id;

 17+16+...+1=153,没错嘿嘿,SQL真棒(我真棒)!

6.连接条件与过滤条件

         在ON语句中使用表连接的连接条件;在WHERE语句中使用选择观测的过滤条件。尽量保持规范,有利于理解和维护,避免不必要的麻烦。

三、WHERE子句

  1. BETWEEN操作符:本质上是两个不严格不等式条件的组合。也就是说,BETEEN a AND b中的a和b是满足过滤条件的。
  2. IN 操作符:指明范围,和SAS中用法相同。可以使用NOT IN来求其补集。
    SELECT accout_id,product_id,cust_id,avail_balance
    FROM account
    WHERE product_cd IN ('CHK','SAV','CD','MM');
  3. 可以使用子查询。
  4. 通配符:_ 表示一个字符 ; %表示任意数目的字符(可以是0)。与LIKE操作符搭配使用。下例表明指定字符串的第二个字必须是a,在它后面需要有一个字母e出现。
    SELECT lname 
    FROM employee
    WHERE lname LIKE '_a%e%';
    

  5. 可以使用正则表达式,它常用于脚本语言,此处不作详述。
  6. null.

null表示缺失值,就如同SAS中数值缺失的 . 与字符缺失的“ ”.注意,表达式可以为null,但不能等于null. 并且,两个null值不能判断为相等

判断是否为null, 使用的语句为  ...WHERE a IS NULL ... 而非  ...WHERE a = NULL ...

注意!如果错写为了等号,程序并不会报错。因此构建测试空值的查询时必须特别小心!

如果要查询不缺失的值,只要使用IS NOT NULL即可,与SAS相同。

四、GROUP BY 和HAVING子句

GROUP BY 根据列值对数据进行分组,也可以用于计数。

 SELECT d.name,count(e.emp_id) as  num_employees

    -> FROM department d INNER JOIN employee e

    -> ON d.dept_id = e.dept_id

    -> GROUP BY d.name

    -> HAVING num_employees > 2;

五、ORDER BY子句

排序  关键字ASC升序  DESC降序   默认升序。

如果根据SELECT子句中的列来排序,可以选择使用该列位于SELECT子句中的位置号来替代列名。比如:

SELECT emp_id,title,start_date,fname,lname

    -> FROM employee

    -> ORDER BY 2,5;

今日命令小结

还没写,嘿嘿,复习的时候再加上

这一篇就包含了SQL学习指南这本书第三到5章的内容啦~小测验还都没有做,这周末把整本书看完之后统一做。还有一句话:嘉伦可以更好看一点吗?小南辰王把我的心都偷走了,哎~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值