#condition
condition::=
condition为条件子句,被应用于WHERE、CHECK等需要进行条件判断的语法场景中,condition将返回true或false值。
YashanDB支持符合SQL标准的各类条件指定:
NOT
=|>|>=|<|<=|!=|<> [ANY|SOME|ALL]
IN|NOT IN
LIKE|NOT LIKE [ESCAPE]
RLIKE|NOT RLIKE
EXISTS|NOT EXISTS
IS NULL|IS NOT NULL
BETWEEN...AND...
ROWNUM
能产生BOOLEAN值的任何表达式
# 比较条件
通过比较符(=|>|>=|<|<=|!=|<>)对其左右两边的表达式进行比较,获得布尔结果。
# any|some
ANY|SOME语法从比较符(=|>|>=|<|<=|!=|<>)右边的集合中选出符合比较条件的子集,然后对左右两边逐一比较,只要获得一个true值,则返回true;全部为false值时,返回false;右边集合为子查询且为空时,返回false。
右边的集合可以为表达式列表,或者子查询语句;对于不指定ANY|SOME的比较,比较符的右边只能为产生单行结果的表达式。
当比较符的左右任一边出现NULL时,均返回false。
示例
--ANY与SOME效果相同
SELECT branch_no,branch_name
FROM branches
WHERE branch_no < ANY('0303','0401');
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0001 深圳
0101 上海
0102 南京
0103 福州
0104 厦门
0201 成都
SELECT branch_no,branch_name
FROM branches
WHERE area_no <> SOME(SELECT area_no FROM area WHERE area_no IN ('01','02'));
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0101 上海
0102 南京
0103 福州
0104 厦门
0401 北京
0402 天津
0403 大连
0404 沈阳
0201 成都
0502 长沙
# all
ALL语法从比较符(=|>|>=|<|<=|!=|<>)右边的集合中选出符合比较条件的子集,然后对左右两边逐一比较,只要获得一个false值,则返回false;全部为true值时,返回true;右边集合为子查询且为空时,返回true。
右边的集合可以为表达式列表,或者子查询语句;对于不指定ALL的比较,比较符的右边只能为产生单行结果的表达式。
当比较符的左右任一边出现NULL时,均返回fals;但对于 NULL > ALL(结果为空的集合),返回true。
示例
SELECT branch_no,branch_name
FROM branches
WHERE branch_no != ALL('0001','0303','0401','0403');
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0101 上海
0102 南京
0103 福州
0104 厦门
0201 成都
0402 天津
0404 沈阳
0502 长沙
# in条件
IN语法将左边集合里的值与右边集合里的值逐一做相等比较,左边的值全部命中则返回true,否则返回false。
右边的集合可以为表达式列表,或者子查询语句(只适用于行存表);当左边为表达式列表时,右边必须为表达式列表的集合,子查询则返回的是对应列表列项的结果集。
示例
--行存表
SELECT branch_no,branch_name
FROM branches b
WHERE (branch_no,area_no) IN
(SELECT b.branch_no,area_no FROM area a
WHERE a.area_no IN ('01','02')
AND a.area_no=b.area_no);
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0101 上海
0102 南京
0103 福州
0104 厦门
0201 成都
--列存表
SELECT branch_no,branch_name
FROM branches b
WHERE SUBSTR(branch_no,1,2) IN ('01','02');
BRANCH_NO BRANCH_NAME
--------- -------------------
0101 上海
0102 南京
0103 福州
0104 厦门
0201 成都
# like条件
LIKE语法需要指定匹配的字符表达式char1与模式串char2,通过匹配算法将字符表达式char1与模式char2做匹配,返回匹配成功true或匹配失败false。其完整语法形式为:
char1 [NOT] LIKE char2 [ESCAPE esc_char].
其中,char1 代表要匹配的字符表达式,char2代表要匹配的模式,esc_char代表escape字符。
LIKE语句执行如下规则:
char1,char2,和esc_char都可以是一个表达式,其结果可以是任何数据类型,当它们的数据类型不一致时,都将转为VARCHAR类型进行判断。
当char1或者char2为NULL时,返回NULL。
char2可以包含特殊的模式匹配字符:下划线 (_) 表示与值中的一个字符完全匹配;百分比符号(%)表示可以匹配值中的零或多个字符(不包括空)。
escape用于转义特殊的模式匹配字符,即将%或_转变为本身的字面意思。如指定了escape,则char2中的esc_char后字符必须为%或_或esc_char自身,否则返回YAS-04428或YAS-04429错误。
esc_char后字符为esc_char自身,表示将其转变为本身的字面意思,如当esc_char为
/
时,模式//
匹配的就是/
这个字符,但///
中的第三个/
将作为转义符。esc_char必须是长度1的字符,也可以是运算后变成长度为1的字符。
示例
--完全匹配
SELECT branch_no,branch_name
FROM branches
WHERE branch_no||'11/1' LIKE '_1__11_1';
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0101 上海
0102 南京
0103 福州
0104 厦门
--转义后无数据满足条件
SELECT branch_no,branch_name
FROM branches
WHERE branch_no||'11/1' LIKE '_1__11/_1' ESCAPE '/';
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
--改为本身字符查找,且去掉其后的_通配符后可以查找到数据
SELECT branch_no,branch_name
FROM branches
WHERE branch_no||'11/1' LIKE '_1__11//1' ESCAPE '/';
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0101 上海
0102 南京
0103 福州
0104 厦门
# rlike条件
RLIKE语法实现功能与REGEXP_LIKE函数相同,通过正则表达式匹配算法将字符表达式expr与正则表达式regexp做匹配,匹配成功返回true,匹配失败返回false。其完整语法形式为:
expr [NOT] RLIKE regexp.
RLIKE语句执行如下规则:
- expr为要匹配的字符表达式,须为字符型,或可转换为字符型的其他类型。
- regexp为要匹配的RegExp,须为字符型,或可转换为字符型的其他类型,长度不超过512字节。
- 当expr或者regexp为NULL时,返回false。
示例
SELECT branch_no,branch_name
FROM branches
WHERE branch_no RLIKE '01[0-9]+';
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0101 上海
0102 南京
0103 福州
0104 厦门
# between and条件
BETWEEN AND语法确定一个表达式的值是否在其他两个表达式定义的间隔内。在语句中出现的三个表达式都必须是数值型、字符型或日期型表达式,当三个表达式的数据类型不一致时,会先进行数据类型的转换,转换失败时返回错误。
示例
SELECT branch_no,branch_name
FROM branches
WHERE branch_no NOT BETWEEN '01' AND '05';
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0001 深圳
0501 武汉
0502 长沙
# rownum_clause
ROWNUM是系统顺序分配的查询返回的行编号,返回的第一行分配的是1,第二行是2,依此类推,它可以用于限制查询返回的总行数。其常用场景为:
1.WHERE条件中做行数限制。
- WHERE ROWNUM< 常数,返回常数-1行的记录。
- WHERE ROWNUM= 常数,因为ROWNUM是从1开始的累加,所以ROWNUM= 1可以返回一条记录;当 ROWNUM= 任何非1值时,条件恒为false,无法返回任何结果。
- WHERE ROWNUM> 常数,常数小于1,则条件恒为true;常数大于等于1,则条件恒为false。
2.ROWNUM与ORDER BY一起使用。
YashanDB对ROWNUM的判断在ORDER BY之前,所以语句是先取出符合ROWNUM条件的记录,然后进行排序。例如:
SELECT score FROM stduents WHERE ROWNUM <= 5 ORDER BY score DESC,这条语句不是返回整个student最高的5个分数记录,而是先根据优化器的选择搜索出5条记录,然后进行排序。
据此规则,如果想得到整个student表前5的排名且只返回这5条记录,可以使用row_limiting_clause中的LIMIT与ORDER BY结合,或者使用ROWNUM子查询。
3.ROWNUM与JOIN一起使用。
在JOIN语句中,ROWNUM与在WHERE中使用相同的规则判断。
ROWNUM在列存中的使用限制
不支持ROWNUM和非常量进行比较。
不支持ROWNUM大于或大于等于任意表达式。
不支持任意表达式小于或小于等于ROWNUM。
ROWNUM在等值比较中只允许等于1,不支持等于其他常数值或者等于非常数。
不支持ROWNUM在or的左右条件中使用。
ROWNUM在过滤条件中只能使用一次。
ROWNUM在过滤条件中只能单独使用,不支持参与运算或作为函数入参。
ROWNUM不能出现在非比较谓词和不等于比较中,例如in。
在外连接的连接条件中不可使用ROWNUM。
示例
SELECT * FROM branches WHERE ROWNUM != 3; --返回ROWNUM为1,2共2条记录
SELECT * FROM branches WHERE ROWNUM != 1; --无记录返回
SELECT * FROM branches WHERE ROWNUM >= 1; --返回全部记录
SELECT * FROM branches WHERE ROWNUM > 1; --无记录返回
SELECT * FROM branches WHERE ROWNUM < 5; --返回ROWNUM为1,2,3,4共4条记录
SELECT * FROM branches WHERE ROWNUM <= 5; --返回ROWNUM为1,2,3,4,5共5条记录
SELECT * FROM branches WHERE ROWNUM = 1; --返回ROWNUM为1共1条记录
SELECT * FROM branches WHERE ROWNUM = 2; --无记录返回
SELECT * FROM branches WHERE ROWNUM BETWEEN 1 AND 8; --返回ROWNUM为1,2..8共8条记录
SELECT * FROM branches WHERE ROWNUM BETWEEN 2 AND 8; --无记录返回
--将ROWNUM用于子查询中,获得前5名记录
SELECT branch_no,branch_name FROM
(SELECT ROWNUM AS rn, a.* FROM branches a ORDER BY branch_no DESC)
WHERE rn<=5;
BRANCH_NO BRANCH_NAME
--------- ----------------------------------------------------------------
0104 厦门
0103 福州
0102 南京
0101 上海
0001 深圳