目录
[1. 简介](#1. 简介)
[2. SQL方言大比拼](#2. SQL方言大比拼)
[2.1. Oracle](#2.1. Oracle)
[2.1.1. 使用ROWNUM实现分页查询](#2.1.1. 使用ROWNUM实现分页查询)
[2.1.2. 使用ROW_NUMBER()实现分页查询](#2.1.2. 使用ROW_NUMBER()实现分页查询)
[2.2. MySQL](#2.2. MySQL)
[2.3. PostgreSQL](#2.3. PostgreSQL)
一、简介
1、SQL是结构化查询语言(Structure Query Language),专门用来操作/访问关系型数据库的通用语言虽然
SQL定义了一套操作关系型数据库统一标准,但是不同数据库之间可能存在SQl方言
2、SQL方言(或者数据库方言)指的是用于访问数据库的结构化查询语言的变体,根据具体的数据库系统不同,也可能
会支持不同的方言,例如:MySQL、Oracle、PostgreSQL 分页查询之间存在SQL方言
二、SQL方言(分页查询为例)
1. 简介
1、Oracle中使用ROWNUM或者ROW_NUMBER()函数实现限制检索行数和分页查询
- 使用ROWNUM实现分页查询
-
- 语法1:随机获取表中的前n条数据
- 语法2:按照某列排序,获取表中的前n条数据(Top-N)
- 语法3:实现分页查询
- 使用ROW_NUMBER()实现分页查询
-
- 语法1:获取表中的前n条数据
- 语法2:实现分页查询
2、MySQL使用LIMIT实现限制检索行数和分页查询
- 语法1:获取表中的前n条数据
- 语法2:LIMIT实现分页查询
- 语法3:LIMIT和OFFSET实现分页查询(兼容PostgreSQL)
3、PostgreSQL使用LIMIT和OFFSET实现限制检索行数和分页查询
- 语法1:获取表中的前n条数据
- 语法2:LIMIT和OFFSET实现分页查询
2. SQL方言大比拼
Oracle、MySQL和PostgreSQL等关系型数据库中基本都支持标准SQL,虽然SQL的基本语法在这些数据库中是
类似的,但是在一些特定的功能和语法上仍然存在差异。
在MySQL和PostgreSQL中,可以使用LIMIT和OFFSET关键字来实现分页查询(限制SELECT语句返回结果行数)
的操作,而Oracle中则需要使用ROWNUM或者ROW_NUMBER()函数实现。
它们的具体用法如下:
2.1. Oracle
Oracle中使用ROWNUM或者ROW_NUMBER()函数实现限制检索行数和分页查询
在Oracle中,使用ROWNUM或者ROW_NUMBER()函数都可以实现分页查询,
用于限制SELECT语句返回结果行数。
具体操作如下:
2.1.1. 使用ROWNUM实现分页查询
语法1:随机获取表中的前n条数据
SELECT *
FROM table_name
WHERE ROWNUM <= n;
语法2:按照某列排序,获取表中的前n条数据(Top-N)
SELECT *FROM (SELECT * FROM table_name ORDER BY table_column)WHERE ROWNUM < n;
语法3:实现分页查询
SELECT *
FROM (SELECT ROWNUM rn, t.* FROM (SELECT * FROM table_name WHERE conditions ORDER BY sort_key) t WHERE ROWNUM <= page_size * page_index
) t1
WHERE rn > page_size * (page_index - 1);
其中,page_size表示每页显示的记录数,page_index表示当前页数。
这个查询语句中,先按照sort_key排序,然后取出前page_size * page_index个记录并加上ROWNUM,
再通过WHERE语句过滤出第page_size * (page_index - 1) + 1到page_size * page_index行的记录。
2.1.2. 使用ROW_NUMBER()实现分页查询
ROW_NUMBER()函数是Oracle 9i及以上版本中引入的一个窗口函数,
在排序后的结果中为每条记录分配一个序号。
通过在SELECT语句中使用ROW_NUMBER()函数,并结合OVER子句和WHERE子句,
也可以实现分页查询的操作,示例代码如下。
语法1:获取表中的前n条数据
SELECT *
FROM (SELECT ROW_NUMBER() OVER (ORDER BY column1, column2) AS rownum, column1, column2FROM table_name
)
WHERE rownum <= :page_size;
其中,table_name为要查询的表名,column1和column2为要排序的列名,:page_size为每页显示的记录数。
上述SQL语句中,ROW_NUMBER()函数会按照column1和column2两个列的升序排列,并为每一行数据分配一
个唯一的序号(rownum)。
然后通过WHERE子句限制查询结果只返回前page_size条记录,即每页显示的数据。
需要注意的是,ROW_NUMBER()函数只能用于查询语句中,不能直接用于更新语句中。
如果需要在更新语句中对数据进行排序,则需要使用ORDER BY子句。
语法2:实现分页查询
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY sort_key) rn, t.* FROM table_name t WHERE conditions
) WHERE rn > page_size * (page_index - 1) AND rn <= page_size * page_index;
SQL语句先按照sort_key排序,然后使用ROW_NUMBER()函数为每条记录分配一个序号,
再通过WHERE语句过滤出第page_size * (page_index - 1) + 1到page_size * page_index行的记录。
总的来说,使用ROWNUM或者ROW_NUMBER()函数都可以实现Oracle中的分页查询,需要根据具体需求选择
合适的语法。
同时,需要注意在使用ROWNUM时要先排序再进行筛选,而使用ROW_NUMBER()则可以在OVER子句中指定排
序方式。
2.2. MySQL
MySQL使用LIMIT实现限制检索行数和分页查询
MySQL中同样提供了限制检索行数语法,但是和Oracle不同使用LIMIT关键字。
在分页查询中,使用LIMIT还可以将结果集分成多个页面。
LIMIT {[offset,] row_count | row_count OFFSET offset}
语法1:获取表中的前n条数据
MySQL使用LIMIT关键字来限制返回结果集中的行数,语法如下:
SELECT *
FROM table_name
LIMIT n;
其中,n为希望返回行数的值。
例:
mysql> select count(*) from actor;
+----------+
| count(*) |
+----------+
| 200 |
+----------+
1 row in set (0.03 sec)mysql> select * from actor limit 10;
+----------+------------+--------------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+--------------+---------------------+
| 1 | PENELOPE | GUINESS | 2006-02-15 04:34:33 |
| 2 | NICK | WAHLBERG | 2006-02-15 04:34:33 |
| 3 | ED | CHASE | 2006-02-15 04:34:33 |
| 4 | JENNIFER | DAVIS | 2006-02-15 04:34:33 |
| 5 | JOHNNY | LOLLOBRIGIDA | 2006-02-15 04:34:33 |
| 6 | BETTE | NICHOLSON | 2006-02-15 04:34:33 |
| 7 | GRACE | MOSTEL | 2006-02-15 04:34:33 |
| 8 | MATTHEW | JOHANSSON | 2006-02-15 04:34:33 |
| 9 | JOE | SWANK | 2006-02-15 04:34:33 |
| 10 | CHRISTIAN | GABLE | 2006-02-15 04:34:33 |
+----------+------------+--------------+---------------------+
10 rows in set (0.00 sec)
语法2:LIMIT实现分页查询
为了实现分页查询,需要限制结果集中的行数同时还要跳过一定的行数,使用LIMIT可以将结果集分成多个页面,
下面是LIMIT语法的详细说明:
SELECT *
FROM table_name
LIMIT offset, row_count;
语法说明:
- offset表示查询结果的起始位置,即跳过多少条记录,取下一条记录作为返回记录。
- row_count表示要返回的记录数,也就是取几条记录。例:如果row_count为5,表示返回5条记录。
- 如果只给出LIMIT row_count,则默认offset为0,从第1条记录开始返回row_count条记录,即LIMIT row_count 等于 LIMIT 0, row_count。
- 如果查询结果不足指定的row_count条记录,则返回实际可用的记录数。
例:查询第2到12条记录
mysql> select * from actor limit 2,10;
+----------+------------+--------------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+--------------+---------------------+
| 3 | ED | CHASE | 2006-02-15 04:34:33 |
| 4 | JENNIFER | DAVIS | 2006-02-15 04:34:33 |
| 5 | JOHNNY | LOLLOBRIGIDA | 2006-02-15 04:34:33 |
| 6 | BETTE | NICHOLSON | 2006-02-15 04:34:33 |
| 7 | GRACE | MOSTEL | 2006-02-15 04:34:33 |
| 8 | MATTHEW | JOHANSSON | 2006-02-15 04:34:33 |
| 9 | JOE | SWANK | 2006-02-15 04:34:33 |
| 10 | CHRISTIAN | GABLE | 2006-02-15 04:34:33 |
| 11 | ZERO | CAGE | 2006-02-15 04:34:33 |
| 12 | KARL | BERRY | 2006-02-15 04:34:33 |
+----------+------------+--------------+---------------------+
10 rows in set (0.00 sec)mysql>
语法3:LIMIT和OFFSET实现分页查询(兼容PostgreSQL)
为了兼容PostgreSQL,MySQL也支持LIMIT row_count OFFSET offset语法。
可以使用LIMIT和OFFSET关键字,语法如下:
SELECT *
FROM table_name
LIMIT n OFFSET m;
其中,n为希望返回的行数,m为需要跳过的行数。
对于上面的【查询第2到12条记录】的例子,还可以用LIMIT row_count OFFSET offset语法实现。
例:
mysql> select * from actor limit 10 OFFSET 2;
+----------+------------+--------------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+--------------+---------------------+
| 3 | ED | CHASE | 2006-02-15 04:34:33 |
| 4 | JENNIFER | DAVIS | 2006-02-15 04:34:33 |
| 5 | JOHNNY | LOLLOBRIGIDA | 2006-02-15 04:34:33 |
| 6 | BETTE | NICHOLSON | 2006-02-15 04:34:33 |
| 7 | GRACE | MOSTEL | 2006-02-15 04:34:33 |
| 8 | MATTHEW | JOHANSSON | 2006-02-15 04:34:33 |
| 9 | JOE | SWANK | 2006-02-15 04:34:33 |
| 10 | CHRISTIAN | GABLE | 2006-02-15 04:34:33 |
| 11 | ZERO | CAGE | 2006-02-15 04:34:33 |
| 12 | KARL | BERRY | 2006-02-15 04:34:33 |
+----------+------------+--------------+---------------------+
10 rows in set (0.00 sec)mysql>
2.3. PostgreSQL
PostgreSQL使用LIMIT和OFFSET实现限制检索行数和分页查询
在 PostgreSQL 中,可以使用 LIMIT 和 OFFSET 子句来限制检索的行数和进行分页查询。
SELECT select_list
FROM table_expression
[ ORDER BY ... ]
[ LIMIT { number | ALL } ] [ OFFSET number ]
语法说明:
- SELECT select_list:从数据库中选取列的列表。您可以指定一个或多个列,使用逗号分隔。如果要检索所有
列的数据,也可以使用通配符 *。
- FROM table_expression:从数据库中选取数据的表名或视图。
- ORDER BY:按升序或降序排列检索的数据。可以根据一个或多个列进行排序,如果没有指定 ORDER BY 子
句,则检索出的数据将以任意顺序返回。
- LIMIT { number | ALL }:限制要返回的记录数的数量。如果指定为数字,则表示要返回的记录数。如果设置
为 ALL,则返回表中的所有记录。
- OFFSET number:从查询的结果集的开头开始省略前 number 个记录。
语法1:获取表中的前n条数据
要限制要检索的行数,可以仅使用 LIMIT 子句。
SELECT * FROM table_name
LIMIT n;
在 PostgreSQL 的 SELECT 查询语句中,LIMIT 子句指定检索记录的最大数量。如果指定了 LIMIT 子句,将只返
回指定数量的记录,即使实际情况下表中存在更多记录。但是,如果查询本身返回的行数少于 LIMIT 子句所指定
的数量,则只会返回查询所产生的行数。
例如,假设执行如下查询:
SELECT * FROM my_table LIMIT 10;
如果 my_table 中只有 5 行,则只返回这 5 行,并且 LIMIT 子句将被保留。如果 my_table 中有 20 行,则只返
回前 10 行。
语法2:LIMIT和OFFSET实现分页查询 *
要执行分页查询,需要同时使用 LIMIT 和 OFFSET 子句。
另外,在进行分页查询时,需要确保在表中有某种排序规则,以便在每次查询时都可以得到正确的结果。
所以通常需要使用 ORDER BY 子句来指定表中的排序规则。
例如,下面是一个分页查询的示例:
-- 创建表 table1
CREATE TABLE table1 (id SERIAL PRIMARY KEY,name VARCHAR(50) NOT NULL,create_date TIMESTAMP NOT NULL
);-- 插入一些数据
INSERT INTO table1 (name, create_date) VALUES
('John', '2022-11-01 09:00:00'),
('Mary', '2022-11-02 10:00:00'),
('Tom', '2022-11-03 11:00:00'),
('Kate', '2022-11-04 12:00:00'),
('Bob', '2022-11-05 13:00:00'),
('Lisa', '2022-11-06 14:00:00'),
('Peter', '2022-11-07 15:00:00'),
('Alice', '2022-11-08 16:00:00'),
('David', '2022-11-09 17:00:00'),
('Jane', '2022-11-10 18:00:00'),
('Alex', '2022-11-11 19:00:00'),
('Sarah', '2022-11-12 20:00:00'),
('Mike', '2022-11-13 21:00:00'),
('Lucy', '2022-11-14 22:00:00');-- 运行查询
SELECT *
FROM table1
ORDER BY create_date
LIMIT 10
OFFSET 10;
执行结果输出例:
mydb1=# select * from table1;id | name | create_date
----+-------+---------------------1 | John | 2022-11-01 09:00:002 | Mary | 2022-11-02 10:00:003 | Tom | 2022-11-03 11:00:004 | Kate | 2022-11-04 12:00:005 | Bob | 2022-11-05 13:00:006 | Lisa | 2022-11-06 14:00:007 | Peter | 2022-11-07 15:00:008 | Alice | 2022-11-08 16:00:009 | David | 2022-11-09 17:00:0010 | Jane | 2022-11-10 18:00:0011 | Alex | 2022-11-11 19:00:0012 | Sarah | 2022-11-12 20:00:0013 | Mike | 2022-11-13 21:00:0014 | Lucy | 2022-11-14 22:00:00
(14 rows)mydb1=# SELECT *
mydb1-# FROM table1
mydb1-# ORDER BY create_date
mydb1-# LIMIT 10
mydb1-# OFFSET 10;id | name | create_date
----+-------+---------------------11 | Alex | 2022-11-11 19:00:0012 | Sarah | 2022-11-12 20:00:0013 | Mike | 2022-11-13 21:00:0014 | Lucy | 2022-11-14 22:00:00
(4 rows)mydb1=#
在上面的示例中,我们创建了一个名为 table1 的表,并插入一些数据。
然后,我们运行了与原始 SQL 语句相同的查询,检索满足条件的前10行,从第11行开始显示。
我们在 create_date 列上对表进行排序,并检索从第11行开始的10行记录。
由于表中仅有14条数据,所以最终的输出为4条数据。
三、语法规范
1、SQL语句可以单行或多行书写,以分号结尾
2、数据库和表名、字段名等对象名中间不要包含空格
3、mysql的sql语法不区分大小写,关键字建议使用大写
4、命名时:尽量使用26个英文字母大小写,数字0-9,下划线,不要使用其他符号
5、建议不要使用mysql的关键字等来作为表名、字段名、数据库名等,如果不小心使用,请在SQL语句中使用(飘号)引起来
6、同一个mysql软件中,数据库不能同名,同一个库中,表不能重名,同一个表中,字段不能重名
四、注释
- 单行注释
-- 注释内容 或 # 注释内容(其中 # 是mysql特有的注释)
- 多行注释
/* 注释内容 */
五、MySQL脚本中的标点符号
- 要求
① 本身成对的标点符号必须成对,例如:(),'',""。
② 所有标点符号必须英文状态下半角输入方式下输入。
- 几个特殊的标点符
① 小括号():在创建表、添加数据、函数使用、子查询、计算表达式等会用 () 表示某个部分是一个整体结构
② 单引号'':字符串和日期类型的数据值使用单引号''引起来,数值类型的不需要加标点符号。
③ 双引号"":列的别名可以使用双引号"",给表名取别名不要使用双引号