Move the docs folder

This commit is contained in:
LINxiansheng
2022-02-10 14:51:49 +08:00
committed by LINxiansheng
parent 7c6dcc6712
commit d42f317422
1160 changed files with 0 additions and 3 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,269 @@
聚集函数
=========================
聚合函数对一组值执行计算并返回单一的值。聚合函数忽略空值。聚合函数经常与SELECT语句的GROUP BY子句一同使用。
所有聚合函数都具有确定性。任何时候用一组给定的输入值调用它们时,都返回相同的值。
在OceanBase的聚合函数中,Value表达式只能出现一个。例如:不支持COUNT(c1, c2),仅支持COUNT(c1)。
AVG
------------
**声明**
`AVG(([DISTINCT] expr)`
**说明**
返回指定组中的平均值,空值被忽略。DISTINCT选项可用于返回expr的不同值的平均值。若找不到匹配的行,则AVG()返回NULL。
**例子**
```javascript
Oceanbase>select * from oceanbasetest;
+----+------+------+
| id | ip | ip2 |
+----+------+------+
| 1 | 4 | NULL |
| 3 | 3 | NULL |
| 4 | 3 | NULL |
+----+------+------+
3 rows in set (0.01 sec)
Oceanbase>select avg(ip2), avg(ip), avg(distinct(ip)) from oceanbasetest;
+----------+---------+-------------------+
| avg(ip2) | avg(ip) | avg(distinct(ip)) |
+----------+---------+-------------------+
| NULL | 3.3333 | 3.5000 |
+----------+---------+-------------------+
1 row in set (0.00 sec)
Oceanbase>select avg(distinct(ip)),avg(ip),avg(ip2) from oceanbasetest;
+-------------------+---------+----------+
| avg(distinct(ip)) | avg(ip) | avg(ip2) |
+-------------------+---------+----------+
| 3.5000 | 3.3333 | NULL |
+-------------------+---------+----------+
1 row in set (0.00 sec)
```
COUNT
--------------
**声明**
`COUNT([DISTINCT] expr)`
**说明**
COUNT(\[DISTINCT\] expr )返回SELECT语句检索到的行中非NULL值的数目。若找不到匹配的行,则COUNT()返回0。DISTINCT选项可用于返回 expr 的不同值的数目。
COUNT(\*)的稍微不同之处在于,它返回检索行的数目,不论其是否包含NULL值。
**例子**
```javascript
Oceanbase>select * from oceanbasetest;
+----+------+------+
| id | ip | ip2 |
+----+------+------+
| 1 | 4 | NULL |
| 3 | 3 | NULL |
| 4 | 3 | NULL |
+----+------+------+
3 rows in set (0.00 sec)
Oceanbase>select count(ip2), count(ip), count(distinct(ip)), count(*) from oceanbasetest;
+------------+-----------+---------------------+----------+
| count(ip2) | count(ip) | count(distinct(ip)) | count(*) |
+------------+-----------+---------------------+----------+
| 0 | 3 | 2 | 3 |
+------------+-----------+---------------------+----------+
1 row in set (0.00 sec)
```
MAX
------------
**声明**
`MAX([DISTINCT] expr)`
**说明**
返回指定数据中的最大值。
MAX()的取值可以是一个字符串参数;在这些情况下,它们返回最大字符串值。DISTINCT关键字可以被用来查找 expr的不同值的最大值,这产生的结果与省略DISTINCT 的结果相同。
假设表a有三行数据:id=1,num=10;id=2,num=20;id=3,num=30。
**例子**
```javascript
Oceanbase>SELECT MAX(num) FROM a;
+-----------------+
| MAX(num) |
+-----------------+
| 30 |
+-----------------+
1 row in set (0.00 sec)
```
MIN
------------
**声明**
`MIN([DISTINCT] expr)`
**说明**
返回指定数据中的最小值。
MIN()的取值可以是一个字符串参数;在这些情况下,它们返回最小字符串值。DISTINCT关键字可以被用来查找expr 的不同值的最小值,然而,这产生的结果与省略DISTINCT 的结果相同。
假设表a有三行数据:id=1,num=10;id=2,num=20;id=3,num=30。
**例子**
```javascript
Oceanbase>SELECT MIN(num) FROM a;
+----------------+
| MIN(num) |
+----------------+
| 10 |
+----------------+
1 row in set (0.00 sec)
```
SUM
------------
**声明**
`SUM([DISTINCT] expr)`
**说明**
返回 expr 的总数。若返回集合中无任何行,则 SUM() 返回NULL。DISTINCT关键字可用于求得 expr 不同值的总和。
若找不到匹配的行,则SUM()返回NULL。
**例子**
```javascript
Oceanbase>select * from oceanbasetest;
+------+------+------+
| id | ip | ip2 |
+------+------+------+
| 1 | 4 | NULL |
| 3 | 3 | NULL |
| 4 | 3 | NULL |
+------+------+------+
3 rows in set (0.00 sec)
Oceanbase>select sum(ip2),sum(ip),sum(distinct(ip)) from oceanbasetest;
+----------+---------+-------------------+
| sum(ip2) | sum(ip) | sum(distinct(ip)) |
+----------+---------+-------------------+
| NULL | 10 | 7 |
+----------+---------+-------------------+
1 row in set (0.00 sec)
```
GROUP_CONCAT
---------------------
**声明**
`GROUP_CONCAT([DISTINCT] expr)`
**说明**
该函数返回带有来自一个组的连接的非NULL值的字符串结果。
```javascript
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
ASC | DESC]
[SEPARATOR str_val])
```
**例子**
```javascript
Oceanbase>select * from book; //表book(书编号,书名,出版社)
+--------+--------------------------------+-----------------------------+
| bookid | bookname | publishname |
+--------+--------------------------------+-----------------------------+
| 1 | git help | alibaba group publisher |
| 2 | MySQL性能优化 | 浙江大学图文出版社 |
| 3 | JAVA编程指南 | 机械工业出版社 |
| 3 | JAVA编程指南 | 机械工业出版社 |
| 4 | 大规模分布式存储系统 | 机械工业出版社 |
+--------+--------------------------------+-----------------------------+
5 rows in set (0.00 sec)
//查找书名信息
Oceanbase>select group_concat(bookname) from book group by bookname;
+-----------------------------------+
| group_concat(bookname) |
+-----------------------------------+
| git help |
| JAVA编程指南,JAVA编程指南 |
| MySQL性能优化 |
| 大规模分布式存储系统 |
+-----------------------------------+
4 rows in set (0.00 sec)
//查找书名信息,书名唯一
Oceanbase>select group_concat(distinct(bookname)) from book group by bookname;
+----------------------------------+
| group_concat(distinct(bookname)) |
+----------------------------------+
| git help |
| JAVA编程指南 |
| MySQL性能优化 |
| 大规模分布式存储系统 |
+----------------------------------+
4 rows in set (0.01 sec)
//查找书名和出版社信息,以书名分组,出版社信息降序排序显示
Oceanbase>select bookname, group_concat(publishname order by publishname desc separator ';' ) from book group by bookname;
+--------------------------------+---------------------------------------------------------------------+
| bookname | group_concat(publishname order by publishname desc separator ';' ) |
+--------------------------------+---------------------------------------------------------------------+
| git help | alibaba group publisher |
| JAVA编程指南 | 机械工业出版社;机械工业出版社 |
| MySQL性能优化 | 浙江大学图文出版社 |
| 大规模分布式存储系统 | 机械工业出版社 |
+--------------------------------+---------------------------------------------------------------------+
4 rows in set (0.00 sec)
```

View File

@ -0,0 +1,425 @@
分析函数
=========================
简介
-----------
**分析函数** (某些数据库下也叫做 **窗口函数** )与聚合函数类似,计算总是基于一组行的集合,不同的是,聚合函数一组只能返回一行,而分析函数每组可以返回多行,组内每一行都是基于窗口的逻辑计算的结果。分析函数可以显著优化需要 self-join 的查询。
### 分析函数语法
"窗口"也称为 FRAME,OceanBase 数据库同时支持 ROWS 与 RANGE 两种 FRAME 语义,前者是基于物理行偏移的窗口,后者则是基于逻辑值偏移的窗口。
分析函数语法如下:
```unknow
analytic_function:
analytic_function([ arguments ]) OVER (analytic_clause)
analytic_clause:
[ query_partition_clause ] [ order_by_clause [ windowing_clause ] ]
query_partition_clause:
PARTITION BY { expr[, expr ]... | ( expr[, expr ]... ) }
order_by_clause:
ORDER [ SIBLINGS ] BY{ expr | position | c_alias } [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ] [, { expr | position | c_alias } [ ASC | DESC ][ NULLS FIRST | NULLS LAST ]]...
windowing_clause:
{ ROWS | RANGE } { BETWEEN { UNBOUNDED PRECEDING | CURRENT ROW | value_expr {
PRECEDING | FOLLOWING } } AND{ UNBOUNDED FOLLOWING | CURRENT ROW | value_expr {
PRECEDING | FOLLOWING } } | { UNBOUNDED PRECEDING | CURRENT ROW| value_expr
PRECEDING}}
```
SUM/MIN/MAX/COUNT/AVG
------------------------------------------
**声明**
SUM 的语法为:`SUM([ DISTINCT | ALL ] expr) [ OVER (analytic_clause) ]`
MIN 的语法为:`MIN([ DISTINCT | ALL ] expr) [ OVER (analytic_clause) ]`
MAX 的语法为:`MAX([ DISTINCT | ALL ] expr) [ OVER (analytic_clause) ]`
COUNT 的语法为:`COUNT({ * | [ DISTINCT | ALL ] expr }) [ OVER (analytic_clause) ]`
AVG 的语法为:`AVG([ DISTINCT | ALL ] expr) [ OVER(analytic_clause) ]`
**说明**
以上分析函数都有对应的聚合函数,其中,`SUM` 返回 `expr` 的和,`MIN`/`MAX` 返回 `expr` 的最小值/最大值,`COUNT` 返回窗口中查询的行数,`AVG` 返回 `expr` 的平均值。
对于 `COUNT` 函数,如果指定了 `expr`,即返回 `expr` 不为 NULL 的统计个数,如果指定 `COUNT(*)` 返回所有行的统计数目。
**例子**
```javascript
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.17 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.03 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.01 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient>select last_name, sum(salary) over(partition by job_id) totol_s, min(salary) over(partition by job_id) min_s, max(salary) over(partition by job_id) max_s, count(*) over(partition by job_id) count_s from exployees;
+-----------+---------+-------+-------+---------+
| last_name | totol_s | min_s | max_s | count_s |
+-----------+---------+-------+-------+---------+
| jim | 2000 | 2000 | 2000 | 1 |
| mike | 36000 | 11000 | 13000 | 3 |
| lily | 36000 | 11000 | 13000 | 3 |
| tom | 36000 | 11000 | 13000 | 3 |
+-----------+---------+-------+-------+---------+
4 rows in set (0.01 sec)
```
NTH_VALUE/FIRST_VALUE/LAST_VALUE
-----------------------------------------------------
**声明**
NTH_VALUE 的语法为:`NTH_VALUE (measure_expr, n) [ FROM { FIRST | LAST } ] [ { RESPECT | IGNORE } NULLS ] OVER (analytic_clause)`
FIRST_VALUE 的语法为:`FIRST_VALUE { (expr) [ {RESPECT | IGNORE} NULLS ] | (expr [ {RESPECT | IGNORE} NULLS ])} OVER (analytic_clause)`
LAST_VALUE 的语法为:`LAST_VALUE { (expr) [ {RESPECT | IGNORE} NULLS ] | (expr [ {RESPECT | IGNORE} NULLS ])} OVER (analytic_clause)`
**说明**
NTH_VALUE 函数表示第几个值,方向由 `[ FROM { FIRST | LAST } ]` 确定,默认为 `FROM FIRST`,含有是否忽略 NULL 值的标志。其窗口为统一的 `analytic_clause`。这里 `n` 应该是正数,如果 `n` 是 NULL,函数将返回错误;如果 `n` 大于窗口内所有的行数,此函数将返回 NULL。
FIRST_VALUE 和 LAST_VALUE 表示从第一个开始计数或者是从最后一个开始计数。
**例子**
```javascript
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.08 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.01 sec)
obclient> select last_name, first_value(salary) over(partition by job_id) totol_s, last_value(salary) over(partition by job_id) min_s, max(salary) over(partition by job_id) max_s from exployees;
+-----------+---------+-------+-------+
| last_name | totol_s | min_s | max_s |
+-----------+---------+-------+-------+
| jim | 2000 | 2000 | 2000 |
| mike | 12000 | 11000 | 13000 |
| lily | 12000 | 11000 | 13000 |
| tom | 12000 | 11000 | 13000 |
+-----------+---------+-------+-------+
4 rows in set (0.01 sec)
```
LEAD/LAG
-----------------------------
**声明**
LEAD 的语法为:`LEAD { ( value_expr [, offset [, default]]) [ { RESPECT | IGNORE } NULLS ] | ( value_expr [ { RESPECT | IGNORE } NULLS ] [, offset [, default]] )} OVER ([ query_partition_clause ] order_by_clause)`
LAG 的语法为:`LAG { ( value_expr [, offset [, default]]) [ { RESPECT | IGNORE } NULLS ] | ( value_expr [ { RESPECT | IGNORE } NULLS ] [, offset [, default]] )} OVER ([ query_partition_clause ] order_by_clause)`
**说明**
LEAD 和 LAG 含义为可以在一次查询中取出当前行的同一个字段的前面或后面第 N 行的数据,这种操作可以使用相同表的自连接来实现,但 LEAD/LAG 窗口函数有更高的效率。
其中,`value_expr` 是要做比对的字段,`offset``value_expr` 的偏移量,`default` 参数的默认值为 NULL,即如果在 LEAD/LAG 没有显示的设置 `default` 值的情况下,返回值为 NULL。例如:对 LAG 来说,当前行为 4,`offset` 值为 6,这时候所要找的数据就是第 -2 行,不存在此行即返回 `default` 的值。
`[ { RESPECT | IGNORE } NULLS ]` 的语法为是否考虑 NULL 值,默认为 `RESPECT`,考虑 NULL 值。
注意 LEAD/LAG 两个函数后必须有 `order_by_clause`,数据应该在一个列上排序之后才能有前多少行后多少行的概念。`query_partition_clause` 是可选的,如果没有 `query_partition_clause`,就是全局的数据。
**例子**
```unknow
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.08 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.01 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> select last_name, lead(salary) over(order by salary) lead, lag(salary) over(order by salary) lag from exployees;
+-----------+-------+-------+
| last_name | lead | lag |
+-----------+-------+-------+
| jim | 11000 | NULL |
| tom | 12000 | 2000 |
| mike | 13000 | 11000 |
| lily | NULL | 12000 |
+-----------+-------+-------+
4 rows in set (0.01 sec)
```
STDDEV/VARIANCE/STDDEV_SAMP/STDDEV_POP
-----------------------------------------------------------
**声明**
VARIANCE 的语法为:`VARIANCE([ DISTINCT | ALL ] expr) [ OVER (analytic_clause) ]`
STDDEV 的语法为:`STDDEV([ DISTINCT | ALL ] expr) [ OVER (analytic_clause) ]`
STDDEV_SAMP 的语法为:`STDDEV_SAMP(expr) [ OVER (analytic_clause) ]`
STDDEV_POP 的语法为:`STDDEV_POP(expr) [ OVER (analytic_clause) ]`
**说明**
VARIANCE 返回的是 `expr` 的方差,`expr` 可能是数值类型或者可以转换成数值类型的类型,方差的类型和输入的值的类型相同。
STDDEV 返回的是 `expr` 的标准差,参数类型方面和 VARIANCE 的相同。
STDDEV_SAMP 返回的是样本标准差。
STDDEV_POP 返回的是总体标准差。
**例子**
```javascript
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.08 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.01 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> select last_name, stddev(salary) over(order by salary) std, variance(salary) over(order by salary) var, stddev_pop(salary) over() std_pop, stddev_samp(salary) over() from exployees;
+-----------+-------------------+--------------------+-------------------+----------------------------+
| last_name | std | var | std_pop | stddev_samp(salary) over() |
+-----------+-------------------+--------------------+-------------------+----------------------------+
| jim | 0 | 0 | 4387.482193696061 | 5066.228051190222 |
| tom | 4500 | 20250000 | 4387.482193696061 | 5066.228051190222 |
| mike | 4496.912521077347 | 20222222.222222224 | 4387.482193696061 | 5066.228051190222 |
| lily | 4387.482193696061 | 19250000 | 4387.482193696061 | 5066.228051190222 |
+-----------+-------------------+--------------------+-------------------+----------------------------+
4 rows in set (0.00 sec)
```
NTILE
--------------------------
**声明**
`NTILE(expr) OVER ([ query_partition_clause ] order_by_clause)`
**说明**
NTILE 函数将分区中已经排序的行划分为大小尽可能相同的指定数量的分组,并返回给每行组号。`expr` 如果是 NULL,则返回 NULL。
例子
```javascript
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.08 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.01 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> select last_name, ntile(10) over(partition by job_id order by salary) ntl from exployees;
+-----------+------+
| last_name | ntl |
+-----------+------+
| jim | 1 |
| tom | 1 |
| mike | 2 |
| lily | 3 |
+-----------+------+
4 rows in set (0.01 sec)
```
ROW_NUMBER
-------------------------------
声明
`ROW_NUMBER( ) OVER ([ query_partition_clause ] order_by_clause)`
说明
ROW_NUMBER 函数按照 `order_by_clause` 子句中指定的行的顺序,为每一行分配一个编号。
例子
```javascript
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.08 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.01 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> select last_name, row_number() over(partition by job_id order by salary) ntl from exployees;
+-----------+------+
| last_name | ntl |
+-----------+------+
| jim | 1 |
| tom | 1 |
| mike | 2 |
| lily | 3 |
+-----------+------+
4 rows in set (0.00 sec)
```
RANK/DENSE_RANK/PERCENT_RANK
-------------------------------------------------
**声** **明**
RANK 的语法为:`RANK( ) OVER ([ query_partition_clause ] order_by_clause)`
DENSE_RANK 的语法为:`DENSE_RANK( ) OVER([ query_partition_clause ] order_by_clause)`
PERCENT_RANK 的语法为:`PERCENT_RANK( ) OVER ([ query_partition_clause ] order_by_clause)`
**说明**
RANK 计算每一行数据在某列上的排序,该列由 `order_by_clause` 中的列决定。例如,按照 salary 排序可以看出员工的收入排名。
DENSE_RANK 的语义基本和 RANK 函数相同,但是 RANK 的排序中间会有'跳过',但是 DENSE_RANK 中不会有。
PERCENT_RANK 的语义基本和 RANK 函数相同,但是 PERCENT_RANK 排序的结果是百分比,计算的是给定行的百分比。
**例子**
```unknow
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.10 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> select last_name, rank() over(partition by job_id order by salary) rank, dense_rank() over(partition by job_id order by salary) dense_rank, percent_rank() over(partition by job_id order by salary) percent_rank from exployees;
+-----------+------+------------+----------------------------------+
| last_name | rank | dense_rank | percent_rank |
+-----------+------+------------+----------------------------------+
| jim | 1 | 1 | 0.000000000000000000000000000000 |
| tom | 1 | 1 | 0.000000000000000000000000000000 |
| mike | 2 | 2 | 0.500000000000000000000000000000 |
| lily | 3 | 3 | 1.000000000000000000000000000000 |
+-----------+------+------------+----------------------------------+
4 rows in set (0.01 sec)
```
CUME_DIST
------------------------------
**声明**
`CUME_DIST() OVER ([ query_partition_clause ] order_by_clause)`
**说明**
该函数计算一个值的分布,返回值为大于 0 小于等于 1 的值。作为一个分析函数,CUME_DIST 在升序情况下计算比当前行的特定列小的数据的占比。例如如下例子中,按 job_id 分组并在薪水排序的情况下,每行数据在窗口内的排序列上的占比。
**例子**
```unknow
obclient> create table exployees(last_name char(10), salary decimal, job_id char(32));
Query OK, 0 rows affected (0.10 sec)
obclient> insert into exployees values('jim', 2000, 'cleaner');
Query OK, 1 row affected (0.11 sec)
obclient> insert into exployees values('mike', 12000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('lily', 13000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> insert into exployees values('tom', 11000, 'engineering');
Query OK, 1 row affected (0.00 sec)
obclient> select last_name, cume_dist() over(partition by job_id order by salary) cume_dist from exployees;
+-----------+----------------------------------+
| last_name | cume_dist |
+-----------+----------------------------------+
| jim | 1.000000000000000000000000000000 |
| tom | 0.333333333333333333333333333333 |
| mike | 0.666666666666666666666666666667 |
| lily | 1.000000000000000000000000000000 |
+-----------+----------------------------------+
4 rows in set (0.01 sec)
```

View File

@ -0,0 +1,94 @@
信息函数
=========================
FOUND_ROWS
-------------------
**声明**
`found_rows()`
**说明**
一个SELECT语句可能包含一个LIMIT子句,用来限制数据库服务器端返回客户端的行数。在某些情况下,我们需要不再次运行该语句而得知在没有LIMIT时到底该语句返回了多少行。我们可以在SELECT语句中选择使用SQL_CALC_FOUND_ROWS, 然后调用FOUND_ROW()函数,获取该语句在没有LIMIT时返回的行数。
例如:
```javascript
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
```
第二个SELECT语句返回一个数字,表示在没有LIMIT子句的情况下,第一个SELECT语句返回了多少行。(若上述的SELECT语句在不使用SQL_CALC_FOUND_ROWS选项时,使用LIMIT和不使用LIMIT时候, FOUND_ROWS()可能会返回不同的结果)。
通过FOUND_ROWS()函数返回的有效行数是瞬时的,并且不能越过SELECT SQL_CALC_FOUND_ROWS语句后面的语句。如果你后续还需要用到这个值,就需要将其保存。
例如:
```javascript
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
mysql> SET @rows = FOUND_ROWS();
```
假如你正在使用SQL_CALC_FOUND_ROWS,系统必须计算出在全部结果集合中有多少行。尽管如此,这也还是比不用LIMIT而再次运行查询要快,原因是结果集合不需要被发送到客户端。
SQL_CALC_FOUND_ROWS和FOUND_ROWS()在当你希望限制一个查询返回的行数时是很有用的,同时还能不需要再次运行查询就可以确定全部结果集合中的行数。一个 **例子** 就是提供页式显示的Web脚本,该显示包含显示搜索结果其他部分的页的链接。使用FOUND_ROWS()使你确定剩下的结果需要多少其他的页。
SQL_CALC_FOUND_ROWS 和 FOUND_ROWS() 的应用对于UNION 查询比对于简单SELECT 语句更为复杂,原因是在UNION 中,LIMIT 可能会出现在多个位置。它可能适用于UNION中的独立的SELECT语句,或是整个的UNION 结果。
SQL_CALC_FOUND_ROWS对于 UNION的期望结果是它返回在没有全局的LIMIT的条件下而应返回的行数。SQL_CALC_FOUND_ROWS 和UNION 一同使用的条件是:
* SQL_CALC_FOUND_ROWS 关键词必须出现在UNION的第一个 SELECT中。
<!-- -->
* FOUND_ROWS()的值只有在使用 UNION ALL时才是精确的。若使用不带ALL的UNION,则会发生两次删除,而FOUND_ROWS() 的指只需近似的。
<!-- -->
* 假若UNION 中没有出现LIMIT ,则SQL_CALC_FOUND_ROWS 被忽略,返回临时表中的创建的用来处理UNION的行数。
LAST_INSERT_ID()
-------------------------
**声明**
`last_insert_id()`
**说明**
返回本session最后一次插入的自增字段值,如最近一条insert插入多条记录,LAST_INSERT_ID()返回第一条记录的自增字段值。
**例子**
```javascript
mysql>select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 5 |
+------------------+
1 row in set (0.00 sec)
```

View File

@ -0,0 +1,185 @@
其它函数
=========================
COALESCE
-----------------
**声明**
`COALESCE(expr, expr, expr,...)`
**说明**
依次参考各参数表达式,遇到非NULL值即停止并返回该值。如果所有的表达式都是空值,最终将返回一个空值。
所有表达式必须是相同类型,或者可以隐性转换为相同的类型。
**例子**
```javascript
Oceanbase>SELECT COALESCE(NULL,NULL,3,4,5), COALESCE(NULL,NULL,NULL);
+---------------------------+--------------------------+
| COALESCE(NULL,NULL,3,4,5) | COALESCE(NULL,NULL,NULL) |
+---------------------------+--------------------------+
| 3 | NULL |
+---------------------------+--------------------------+
1 row in set (0.00 sec)
```
NVL
------------
**声明**
`NVL(str1,replace_with)`
**说明**
如果 str1 为 NULL,则替换成 replace_with。
任何时候给它一个空值,它都返回一个你所选择的值。这种能够自动替换空值的能力有助于提供看上去更为完善的输出。其中 str1 一般是一个列名。replace_with 可以是任何值:直接值(即硬编码)、对其他列的引用或者表达式。
**例子**
```javascript
Oceanbase>SELECT NVL(NULL, 0), NVL(NULL, 'a');
+--------------+----------------+
| NVL(NULL, 0) | NVL(NULL, 'a') |
+--------------+----------------+
| 0 | a |
+--------------+----------------+
1 row in set (0.00 sec)
```
SLEEP
--------------
**声明**
`SLEEP(duration)`
**说明**
SLEEP函数根据duration指定的数值暂停相应的时间(单位为秒),并在暂停结束后返回0。
如果SLEEP单独执行且没有被中断,返回结果0;
如果SLEEP单独执行期间被中断,返回结果1,但不会返回任何错误码;
如果SLEEP是查询的一部分,且暂停期间被中断,将会返回错误码1317;
**例子**
```javascript
mysql> SELECT SLEEP(1000);
+------------------+
| SLEEP(1000) |
+------------------+
| 0 |
+------------------+
mysql> SELECT SLEEP(1000);
+------------------+
| SLEEP(1000) |
+------------------+
| 1 |
+------------------+
mysql> SELECT 1 FROM t1 WHERE SLEEP(1000);
ERROR 1317 (70100): Query execution was interrupted
```
全文查找函数
---------------
**声明**
```javascript
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
search_modifier:
{
IN NATURAL LANGUAGE MODE
| IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
| IN BOOLEAN MODE
| WITH QUERY EXPANSION
}
```
**说明**
OceanBase1.0已经支持使用全文查找函数来对全文索引进行查找,并且使用全文查找函数有以下要求:
* 全文查找函数MATCH(col1,col2,...)中指定的列上必须有全文索引(OB目前只支持FULLTEXT CTXCAT索引)
<!-- -->
* 在FULLTEXT CTXCAT索引中,全文查找函数MATCH(col1,col2,...)中指定的列必须完整的覆盖索引中的全文列,例如FULLTEXT INDEX(c1, c2, c3), CTXCAT(c2, c3) 必须是 MATCH(c2,c3) 才能完全的匹配
<!-- -->
* 全文查找函数可以通过上述的关键字来指定查找模式(OB目前只支持NATURAL LANGUAGE MODE和BOOLEAN MODE两种模式),缺省是NATURAL LANGUAGE MODE
默认情况下或者指定IN NATURAL LANGUAGE MODE标示符,MATCH...AGAINST将使用NATURAL LANGUAGE模式来进行全文查找,在NATURAL LANGUAGE模式下,AGAINST接受一个查找字符串,并且按照字符集的比较方式在索引中进行查找,对于表中的每一行数据,MATCH的返回值代表了查找字符串和行中数据的相关度,也就是查找字符串中的文本和数据表中的文本相似度。在默认情况下,OB创建的字符串相关的列是大小写不敏感的,因此,全文查找的关键字是不区分大小写的。如果需要区分大小写,可以为创建全文索引的列指定大小写敏感的数据类型,例如UTF8MB4_BIN。如果MATCH...AGAINST函数被用在WHERE子句中,MATCH被用来过滤跟关键字相关度不匹配的数据,MATCH...AGAINST=0表示没有和关键字相似的数据,目前OB只支持MATCH...AGAINST=0和MATCH...AGAINST\>0两种形式,即完全不相关或者有任意一个关键字相关即可。AGAINST参数中可以接受多个关键字,关键字之间使用' '隔开,表示OR关系,只要有任意一个关键字匹配,即认为符合查找的要求。
OB可以通过使用IN BOOLEAN MODE关键字来进行BOOLEAN模式的全文查找。在这种模式中,关键字前面一些特殊的操作符含有特殊的语义。例如:
```javascript
SELECT * FROM t1 WHERE MATCH (a, b) AGAINST ('菊花 茉莉花' IN BOOLEAN MODE);
+----+------------+------------+
| id | a | b |
+----+------------+------------+
| 1 | 支付宝 | 菊花茶 |
| 2 | 淘宝 | 茉莉花 |
+----+------------+------------+
SELECT * FROM t1 WHERE MATCH (a, b)
AGAINST ('+菊花 -茉莉花' IN BOOLEAN MODE);
+----+------------+------------+
| id | a | b |
+----+------------+------------+
| 1 | 支付宝 | 菊花茶 |
+----+------------+------------+
```
OB的BOOLEAN全文查找目前支持以下几种操作符:+ 代表AND关系,表示查找结果中同时要包含被+修饰的关键字- 代表NOT关系,表示查找结果中不能包含被-修饰的关键字。
```javascript
(no operator) 代表OR关系表示查找结果中只要包含任意一个没有操作符修饰的关键字即可
```
在BOOLEAN全文查找模式中有以下几点需要注意:操作符必须位于关键字的前面,关键字后面的操作符没有修饰意义,例如+菊花是有意义的操作符修饰,而菊花+中的操作符没有修饰意义。操作符和关键字必须紧密相连,不能被其它符号分割开,否者没有修饰意义,例如:+ 菊花前面的操作符没有修饰意义。