简书上的产品经理文章大全0岁的产品经理

SQL进阶之检索数据

2018-05-13  本文已影响25人  Kince_X

sql是使用最广泛的数据库语言。不管你是应用开发者、数据库管理员、web应用设计师web、移动应用开发员,还是只是使用Microsoft office掌握良好的sql知识,对用好数据库都是很重要的。

本文主要是根据大家需要了解的sql知识,从简单的数据库检索入手,逐步过渡到一些较为复杂的内容。希望能够帮助大家循序渐进,系统而直接的学习到sql的知识和技巧。

本文适合以下读者:

sql新手;

希望快速学会并熟练使用sql;

希望在无人帮助的情况下有效而快速地使用sql;


一般sql可以应用到任何数据库管理系统(DBMS),但是各种sql实现不尽相同。本书介绍的sql主要是用于以下系统。
Apache Open Office Base;
IBM DB2;
Microsoft Access;
Microsoft SQL Server;
MariaDB;
Oracle(包括Oracle Express)
PostgreSQL;
SQLite;

第一章节:了解SQL

1.1数据库基础

数据库是一个以某种有组织的方式存储的数据集合。最简单的办法是将数据库想象为一个文件柜。这个文件柜是一个存放数据的物理位置。不管数据是什么,也不管数据是如何组织的。

数据库的定义:保存有组织的数据的容器。通常是一个文件或一组文件。

人们通常用数据库这个术语来代表他们使用的数据库软件。这是不正确的也因此产生了许多混淆。确切的说数据库软件应称为数据库管理系统dbms。数据库是通过dbms创建和操纵的容器。而具体他究竟是什么。形式如何?各种数据库都不一样。

你在往文件柜里放置料时,并不是随便将他们扔进某个抽屉就完事了。而是在文件柜中创建文件,然后将相关的资料放入待定的文件中。

在数据库领域中,这种文件称为表。表示一种结构化的文件,可以用来存储某种特定类型的数据。表可以保存顾客清单产品目录或者其他信息清单。

表的定义:某种特定类型数据的结构化清单。

存储在表中的数据是同一种类型的数据或清单。数据库中的每个表都有一个名字来标识自己。这个名字是唯一的,即数据库中没有其他表具有相同的名字。

使表名成为唯一的实际上是数据库名和表名的组合。有的数据库还是用数据库拥有者的名字作为唯一名的一部分。也就是说,虽然在相同数据库中不能两次使用相同的表名。但在不同的数据库中,完全可以使用相同的表名。

表具有一些特性,这些特性定义了数据在表中如何存储,包含存储什么样的数据?数据如何分解。部分信息如何命名短信息。描述表的这组信息就是所谓的模式。模式可以用来描述数据库中特定的表。也可以用来描述整个数据库(和其中表的关系)。

模式的定义:关于数据库和表的布局及特性的信息。

表由列组成,列存储表中某部分的信息。

列的定义:表中的一个字段。所有表都是由一个或多个列组成的。

理解列的最好办法就是将数据库表想象为一个网格。就像个电子表格那样,网格中每一列存储着某种特定的信息,比如在顾客表中,一列存储顾客编号,另一列存储顾客姓名,而地址、城市、州以及邮政编码全部存储在各自的列中。

正确的将数据分解为多个列极为重要。例如,城市、州、邮政编码应该总是彼此独立的列。通过分解这些数据,才有可能利用特定的列对数据进行分类和过滤(如找出特定州和特定城市的所有顾客)。如果城市和州组合在一个列中,则按周进行分类和过滤,就会很困难。

数据库中,每个列都有相应的数据类型,定义了列可以存储哪些数据种类。

数据类型的定义:所允许的数据的类型。每个表列都有相应的数据类型,他限制或允许该列中存储的数据。

注意数据类型兼容数学类型及其名称是sql不兼容的一个主要原因。虽然大多数基本数据类型得到了一致的支持,但许多高级的数据类型却没有。更糟的是,偶然会有相同的数据类型在不同的dbms中具有不同的名称。对此用户毫无办法,重要的是在创建表结构时,要记住这些差异。

表中的数据是按行存储的。所保存的每个记录存储在自己的行内。如果将表想象为网格,网格中垂直的列为表列,水平为表行。

行的定义:表中的一个记录。

表中每一行都应该有一列或几列可以唯一标示自己。顾客表,可以使用顾客编号,而订单表可以使用订单id。雇员表可以使用雇员id和雇员社会安全号。

主键的定义:一列或一组列。其值能够唯一标识表中的每一行。

唯一标识表中每行的这个列(或这几列),成为主键。主键用来表示一个特定的行。没有主键更新和删除表中特定行就极为困难,因为你不能保证操作只涉及相关的行。

表中的任何列都可以作为主键。只要他满足一下条件

任意两行都不具有相同的主键值。

每一行都必须具有一个主键值。主键列不允许NULL值。

主键列中的值不允许修改后更新。

主键值不能重用。(如果某行从表中删除,他的主键不能赋予给以后的新行。)

1.2什么是sql

sql是一种专门用来与数据库沟通的语言。

设计sql的目的是很好的完成一项任务。提供一种从数据库中读写数据的简单有效的方法。

sql有如下的优点:
sql不是某个数据库供应商专有的语言。几乎所有重要的dbms都支持sql。所以学习此语言时,你几乎能与所有数据库打交道。
sql简单易学。他的语句全都是具有很强描述性的英语单词组成,而且这些单词的数目不多。
sql虽然看上去很简单,但实际上是一种强有力的语言灵活使用,其原因元素可以进行非常复杂和高级的数据库操作。

第二章节检索数据

2.1select语句

正如第一章节所述,sql语句是由简单的英语单词构成。这些单词称为关键字。每个sql语句都是由一个或多个关键词构成的。最经常使用的sq语句,大概就是select语句了。它的用途是从一个或多个表中检索信息。

关键词的定义:作为sql组成部分的保留字。关键词不能用做表和列的名字。

为了使用select检索表数据。必须至少给出两条信息。想选择什么,以及从什么地方选择。

重要的是要理解sql是一种语言,而不是一个应用程序。具体如何写sql语句并显示语句输出,是随不同的应用程序而变化的。

2.2检索单个列

我们将从简单的sqlselect语句讲起,此语句如下所示。

输入:
SELECT prod_name
FROM Products;
分析:
上述语句利用SELECT语句从Products中检索一个名prod_name的列。所需的列名写在SELECT关键字之后。FROM关健词指出从哪个表中检索数据,此语句的输出如下所示。

输出:
prod_name
--------------------------------
fish bean bag toy
bird bean bag toy
Rabbit bean bag toy
8 inch teffy bear
12 inch teffy bear
Raggedy Ann
King doll
Queen doll

说明

如果你自己试验这个查询,可能会发现显示输出的数据顺序与这里的不同。出现这种情况很正常,如果没有明确排序查询结果,在返回的数据没有特定的顺序。返回的数据顺序可能是数据被添加到表中的顺序,也可能不是。只要返回相同数目的行,就是正常的。

说明:结束sql语句

多条sql语句必须以分号分隔。

说明:sql语句和大小写

sql语句,不区分大小写。因此SELECT与select是相同的。同样写成Select也没有关系。许多sql开发人员喜欢对SQL关键字使用大写。而对列名和表名使用小写。这样做使代码更易阅读和调试。

说明:使用空格

在处理sql语句时,其中所有空格都被忽略。sql语句可以写成长长的一行,也可以分写成多行。

多数sql开发人员认为,将sql语句分成多行更容易阅读和调试。

2.3检索多个列

要想从一个表中检索多个列,仍然使用相同的select语句。唯一的不同,是必须在select关键字后给出多个列名,列名之间必须以逗号分隔。

提示:担心逗号

在选择多个列时一定要在列名之间加上逗号。但最后一个列名字后不加。如果在最后一个列名后加了逗号,将出现错误。

下面的select语句从prd ucts表中选择三列。

输入:
SELECT prod_id,prod_name,prod_price
FROM Products;

分析:
与前一个例子一样,这条语句使用select语句从表products中选择数据。在这个例子中,指定了三个列名,列名之间用逗号分隔,词此语句的输出如下。
输出:
prod_id    prod_name  prod_price
----------    -------------    ------------
BNBG01  Fish bean bag toy  3.4900
BNBG02  Bird bean bag toy  3.4900
BNBG03  Rabbit bean bag toy  3.4900
BR01  8 inch teddy bear  5.9900
BR02  12 inch teddy bear  8.9900
BR03  18 inch teddy bear  11.9900
RGAN01  Raggedy Ann  4.9900
RYL01  King doll  9.4900
RYL02  Queen doll  9.4900

说明数据表示:

从上述输出可以看到sql语句一般返回原始的无格式的数据。数据的格式化是表示问题,而不是检索问题。因此表示一般在显示该数据的应用程序中规定,通常很少直接使用,实际检索出的数据。

2.4检索所有列

除了指定所需的列外,select语句还可以检索所有的列而不必逐个列出他们在实际列名的位置使用,星号*通配符可以做到这一点。如下所示。

输入:
SELECT*
FROM Products;
分析
如果给定一个通配符,则返回表中所有列。列的顺序一般是在列在表定义中出现的物理顺序,但并不总是如此,不过sql数据很少这样(通常,数据返回给应用程序,根据需要进行格式化,再表示出来)。因此这不应该造成什么问题。

注意:使用通配符

一般而言,除非你确实需要表中的每一列,否责最好别使用*通配符。虽然使用通配符能让你自己省事,不用明确列出所需列。但检索不需要的列,通常会降低检索和应用程序的性能。

提示:检索未知列

使用通配符有一个大优点。由于不明确指定列名,所以能检索出名字未知的列。

2.5检索不同的值

如前所述,select语句返回所有匹配的行。但是如果你不希望每个值每次都出现。该怎么办呢?例如你想检索products表中所有产品供应商的id。

输入
SELECT vend_id
FROM Products;

输出
vend_id
---------
BRS01
BRS01
BRS01
DLL01
DLL01
DLL01
DLL01
FNG01
FNG01

serect语句返回九行,即使表中只有三个产品供应商,因为。prd ucts表中有九种产品。那么如何检索出不同的值。

办法就是使用DISTINCT关键字,顾名思义,它指示数据库只返回不同的值。

输入:
SELECT DISTINCT vend_id
FROM Products;

分析
SELECT DISTINCT vend_id告诉dbms只返回不同,具有唯一性的vend_id行。所以,正如下面的输出,只有三行。如果使用DISTINCT关键字,它必须直接放在列名的前面。

输出:
vend_id
---------
BRS01
DLL01
FNG01

注意:不能部分使用DISTINCT

DISTINCT关键是作用于所有的列。不仅仅是跟在其后的那一列。例如,你指定SELECT DISTINCT vend_id,prod_price,因为指定的两列不完全相同。所以所有的行都会被检索出来。

2.6限制结果

SELECT语句返回指定表中所有匹配的行,很可能是每一行。如果你只返回第一行或者一定数量的行,该怎么办呢?这是可行的,然后遗憾的是,各种数据库中的这一Sql实现并不相同。

在SQL Server和Access中使用Select时,可以使用top关键字来限制最多返回多少行,如下所示。

输入:
SELECT TOP 5 prod_name
FROM Products;

输出:
prod_name
-----------------------------
8 inch teddy bear
12 inch teddy bear
18 inch teddy bear
fish bean bag toy
bird bean bag toy

分析:
上面代码使用了SELECT TOP 5 语句,只检索前五行数据。

如果你使用的是DB2。很可能习惯使用下面这一DBMS特定的sql语句,像这样。

输入:
SELECT prod_name
FROM Products
FETCH FIRST 5 ROWS ONLY;

分析:
FETCH FIRST 5 ROWS ONLY 就会按字面的意思去做的。

如果你使用Oracle,需要基于(行计数器)来计算行,像这样。

输入
SELECT prod_name
FROM Products
WHERE ROWNUM <=5;

如果你使用MYSQL、MariaDB、PostgreSQL或者SQLite,需要使用LIMIT子句,像这样:

输入:
SELECT prod_name
FROM Products
LIMIT 5 ;

分析:
上述代码使用SELECT语句来检索单独的一列数据。LIMIT5 指示MySQL等DBMS返回不超过5行的数据,这个语句的输出参见下面的代码。

为了得到后面的五行数据,需要指定从哪儿开始以及检索的函数,像这样。

输入
SELECT prod_name
FROM Products
LIMIT 5 OFFSET 5 ;

分析:LIMIT 5 OFFSET 5 指示MySQL等DBMS返回从第5行起的5行数据。第一个数字是检索的行数,第二个数字是指从哪儿开始。这个语句的输出是:

输出:
prod_name
---------------------
Rabbit bean bag toy
Raggedy Ann
King doll
Queen doll

所以,LILMIT指定返回的函数。LIMIT带的OFFSET指定从哪儿开始?在我们的例子中prducts表中只有九种产品,所以LIMIT 5 OFFSET 5 只返回了四行数据(因为没有第五行。)

注意:第0行

第一个被检索的含是第0行,而不是第1行,因此,LIMIT 1 OFFSET1 会检索第2行,而不是第1行。

2.7使用注释

可以看到,sql语句是dbms处理的指令,如果你希望包括不进行处理和执行的文本该怎么办呢?为什么你想要这么做呢?原因有以下几点。

我们这里使用的sql语句都很短,也很简单。然而随着sql语句变长,复杂性增加,你就会想添加一些描述性的注释,这便于你自己今后参考,或者工项目后续参与人员参考。这些注释需要嵌入在sql脚本中,但显示不能进行实际的dbms处理。

这同样适用于sql文件开始处的内容。它可能包含程序员的联系方式,程序描述以及一些说明。

注视的另一个重要应用是暂时停止要执行的sql代码。如果你碰到一个长sql语句,而只想测试它的一部分,那么应该注释掉一些代码,以便DBMS将其视为注释而加以忽略。

很多DBMS都支持各种形式的注释语法。我们先来看行内注释。

输入
SELECT prod_name  -- 这是一条注视
FROM Products;

分析:
注视使用-- (两个连字符)嵌在行内。-- 之后的文本就是注视,例如:这用来描述 CREATE TABLE 语句中的列就很不错。

下面是另一种形式的行内注释(虽然这种形式很少得到支持)

输入:
#这是一条注释
SELECT prod_name
FROM Products;

分析:
在一行的开始处使用#,这一整行都将作为注释。

也可以进行多行注释,注释可以在脚本的任何位置停止和开始。

输入:
/*SELECT prod_name, vend_id
FROM Products;*/
SELECT prod_name
FROM Products;

分析:
注释从*/开始,到*/结束,/*和*/之间的任何内容都是注释。这种方式常用于给代码加注释。就这个例子演示的这里定义了两个sSELECT语句,但是第一个不会执行,因为他已经被注释掉了。
上一篇下一篇

猜你喜欢

热点阅读