_2_ SQL 检索数据

2018-06-20  本文已影响5人  changsanjiang

本文 DEMO:

https://gitee.com/changsanjiang/SQLDemo/tree/master

SELECT 语句

SQL 语句由简单的英语单词构成. 这些单词称为关键字, 每个SQL语句都是由一个或多个关键字构成的. 最常使用的SQL语句大概就是SELECT语句了. 它的用途是从一个或多个表中检索信息.

**关键字**
作为SQL组成部分的保留字. 关键字不能用作表或列的名字.

为了使用SELECT检索表数据, 必须至少给出两条信息:

  1. 想选择什么
  2. 从什么地方选择

下面我们从简单的 SQL SELECT 语句学起吧.

检索单个列

-- 输入: 
SELECT prod_name    -- 想选择什么
FROM Products;      -- 从什么地方选择

如上, 同很多编程语言一样, sql 也支持写注释, 其中 -- 即为注释开头, 另外还可以像C语言一样使用/* ... */来进行注释.

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

prod_name
Fish bean bag toy
Bird bean bag to
Rabbit bean bag toy
**提示: 结束SQL语句**
多条SQL语句必须以分号(;)分隔. 大多数的DBMS不需要在单条SQL语句后加分号, 但也有DBMS可能必须在单条SQL语句后加上分号. 
当然, 如果愿意可以总是加上分号, 这并没有坏处.
** 提示: SQL语句和大小写**
请注意, SQL语句不区分大小写, 因此SELECT与select是相同的 同样, 写成Select也没有关系. 
不过, 一定要认识到虽然SQL是不区分大小写的, 但是 表名, 列名和值可能有所不同(这依赖于具体的DBMS及其如何配置).
**提示: 使用空格**
在处理SQL语句时, 其中所有空格都被忽略. SQL语句可以写成长长的一行, 也可以分写成多行. 
下面这3种写法的作用是一样的

SELECT prod_name
FROM Products;

SELECT prod_name FROM Products;

SELECT 
prod_name
FROM
Products;

检索多个列

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

**提示: 当心逗号**
在选择多个列时, 一定要在列名之间加上逗号, 但最后一个列名后面不加. 
如果加上, 将会出现错误.
-- 输入
SELECT prod_id, prod_name, prod_price
FROM Products;

输出如下:

prod_id prod_name prod_price
1 Fish bean bag toy 12.3
2 Bird bean bag toy 3.49
3 Rabbit bean bag toy 2.1
**说明: 数据表示
从上述输出可以看到, SQL语句一般返回原始的, 无格式的数据. 
数据的格式化是表示问题, 而不是检索问题. 
因此, 表示(如吧上面的价格值显示为正确的十进制数值货币金额)一般在显示该数据的应用程序中规定. 
通常很少直接使用实际检索出的数据.

检索所有列

除了指定所需的列外(如上所述, 一个或多个列), SELECT语句还可以检索所有的列而不必逐个列出他们. 如下, 使用通配符*可以做到这一点.

-- 输入
SELECT *
FROM Products;

分析:
如果给定一个通配符*, 则返回表中所有列. 列的顺序一般是其在表定义中出现的物理顺序, 但并不总是如此. 不过这并不会造成什么问题, 因为通常, 数据返回给应用程序, 还会根据需要进行格式化, 再表示出来.

** 注意: 使用通配符**
一般而言, 除非你确实需要表中的每一列, 否则最好别使用通配符. 
虽然使用通配符能让自己省事, 不用明确列出所有列, 但检索不需要的列通常会降低检索和应用程序的性能.
**搜索未知列**
使用通配符有一个大优点. 由于不明确指定列名(因为星号检索每一列), 所以能检索出名字未知的列.

检索不同的值

如果你不想在检索出的数据中出现重复数据, 该怎么办呢? 例如, 你想检索 products 表中所有产品供应商的ID:

-- 输入
SELECT vend_id
FORM Products;

输出: (以后改为模拟器, 第一行为列名, 其余行为检索结果)


image.png

因为 products 有9种产品, 所以SELECT语句返回了每条产品的供应商, 但是可以看到在返回的数据中有重复的供应商, 那如何只检索出不同的值?

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

-- 输入
SELECT DISTINCT vend_id
FROM Products;

分析:
SELECT DISTINCT vend_id 告诉DBMS只返回不同(具有唯一性)的vend_id行, 所以正如下面的输出, 只有3行. 如果使用 DISTINCT关键字, 必须将其放到列名的前面.

输出:


image.png

另外注意: DISTINCT关键字作用于所有的列, 不仅仅是跟在其后的那一列.
例如, 你指定 SELECT DISTINCT vend_id, prod_price, 只有在两列数据与其余数据不同时, 才会被列举出来. 一图胜千言, 请看如下输出:

-- 输入(未使用DISTINCT)
SELECT vend_id, prod_price
FROM Products;

输出:

image.png

可以看到 DLL01 | 3.49 多次出现. 我们可以使用如下操作, 过滤这几个重复数据行.

-- 输入
SELECT DISTINCT vend_id, prod_price
FROM Products;

输出:

image.png

由上, DLL01 | 3.49 只出现一次.


限制结果行数

我们之前使用的SELECT 语句, 会返回指定表中所有匹配的行. 但是如果我们想只返回第一行或者一定数量的行, 该怎么办呢? 这是可行的, 然而遗憾的是, 各种数据库中的这一SEL实现并不相同.
笔者只关注iOS平台, 故此只看一下iOS平台下的SQLite.

SELECT prod_name
FROM Products
LIMIT 5;

分析:

上述代码使用SELECT语句来检索一列数据. LIMIT 5指示DBMS返回不超过5行的数据. 输出请如下图:

image.png

现在我们知道了限制返回结果行数, 那如何指定从哪儿开始检索呢? 像这样:

SELECT prod_name
FROM Products
LIMIT 5 OFFSET 5;

分析:

LIMIT 5 OFFSET 5 指示DBMS返回从第5行起的5行数据. LIMIT 5 表示检索出5行数据, OFFSET 5 表示从第5行开始, 包括第5行, 也就是 5, 6, 7, 8, 9.

输出:

image.png

在本例中, 由于测试数据只有9种产品, 因此OFFSET 5之后, 就是 5, 6, 7, 8行有数据了. 到第9行就没数据了(从0开始)

**注意: 第0行
第一个被检索的行是第0行, 而不是第1行. 

简化写法:

SELECT prod_name
FROM Products
LIMIT 3,5

LIMIT 3, 5 使用这个语法, 逗号之前的值对应的OFFSET, 之后的值对应的LIMIT.

上一篇 下一篇

猜你喜欢

热点阅读