大多数SQL语句可以包含从数据中计算新值的标量表达式。例如,在查询SELECT ceil(num) FROM a
中,表达式ceil(num)
计算列中值的四舍五入值。
标量表达式产生适合存储单个表格单元格(一行一列)中的值。它们可以与表达式和选择查询进行对比,后者产生结构化的结果。
常量表达式表示一个不变的简单值。
查询中的表达式可以通过两种方式引用当前数据源中的列:
列的名称
SELECT "Default" FROM conf
。SELECT res.num FROM res
。列的序号位置
SELECT @1 FROM res
选择res
中的第一列。以一元运算符为前缀的表达式,或由二元运算符分隔的两个表达式构成一个新表达式。
有关Hubble运算符的完整列表,以及有关它们的优先顺序以及每个运算符的有效操作数的数据类型的详细信息,请参阅函数。
标准运算符<
(小于)、>
(大于)、<=
(小于或等于)、>=
(大于或等于)、=
(等于)<>
和!=
(不等于 )、(IS
等于)和(IS NOT
不等于) ) 可以应用于来自单一数据类型的任何一对值,以及来自不同数据类型的一些值对。
以下特殊规则适用:
NULL
总是比其他所有值都小,甚至是它自己。NULL
,请使用IS
运算符或条件表达式IFNULL(...)
。语法:
<expr> <comparison> ANY <expr>
<expr> <comparison> SOME <expr>
<expr> <comparison> ALL <expr>
值比较运算符<
, >
, =
, <=
,>=
,<>
和 !=
以及模式匹配运算符[NOT] LIKE
可用于将左侧的单个值与右侧的多个值进行比较。
这是通过使用关键字ANY/SOME/ALL
或组合运算符来完成的。
比较结果为真当且仅当:
ANY/SOME
,左侧值的比较对于右侧的任何元素都是true
。ALL
,对于右侧的每个元素,左侧值的比较都为真。比如:
SELECT 1 = ANY (1, 2, 3) as bools;
bools
---------
true
SELECT 1 = ALL (1, 2, 3) as bools;
bools
---------
false
SELECT 4 = ANY ARRAY[56, 4, 10] as bools;
bools
---------
true
语法:
<expr> IN <expr>
<expr> IN ( ... subquery ... )
<expr> NOT IN <expr>
<expr> NOT IN ( ... subquery ... )
当且仅当左操作数的值是计算右操作数的结果的一部分时才返回TRUE
。
select ('a') in (select * from abc);
select a in (1, 2, 3) from test_table;
语法:
<expr> LIKE <expr>
<expr> NOT LIKE <expr>
将两个表达式都计算为字符串,然后测试左侧的字符串是否与右侧给出的模式匹配。
模式可以包含_
匹配任何单个字符,或%
匹配任何零个或多个字符的序列。
例如:
SELECT 'tuesday' LIKE '%day' AS a, 'tursday' LIKE 'tur_day' AS b;
a | b |
------+-------
true| true |
语法:
<expr> ~ <expr>
<expr> ~* <expr>
<expr> !~ <expr>
<expr> !~* <expr>
将两个表达式都计算为字符串,然后测试左侧的字符串是否与右侧给出的模式匹配。
带有星号的*
使用不区分大小写的匹配;否则匹配区分大小写。
与LIKE
模式不同,正则表达式可以匹配字符串中的任何位置,而不仅仅是开头。
例如:
select 'tuesday' ~ 'day' AS x, 'tuesday' ~ 't[uU][eE]sday' AS y, 'tuesday' ~* 'T.*y' AS z;
x | y | z
-------+------+-------
true| true | true
语法:
<expr> SIMILAR TO <expr>
<expr> NOT SIMILAR TO <expr>
将两个表达式都计算为字符串,然后测试左侧的字符串是否与右侧给出的模式匹配。
该模式使用SQL标准的正则表达式定义来表示。这是 SQL中LIKE
模式和 POSIX正则表达式的混合:
_
和%
分别表示任何字符或任何字符串。.
专门匹配句点字符,不像在 POSIX中它是通配符。LIKE
,与POSIX正则表达式不同)。例如:
select 'tuesday' SIMILAR TO '__esday' AS x, 'tuEsday' SIMILAR TO 't[uU][eE]sday' AS y, 'tuesday' SIMILAR TO 'tu%y' AS z;
x | y | z
-------+------+-------
true| true | true
语法:
<name> ( <arguments...> )
内置函数名称后跟左括号,后跟逗号分隔的表达式列表,后跟右括号。
这会将命名函数应用于括号之间的参数。当函数的命名空间没有前缀时, 名称解析规则决定调用哪个函数。
此外,还支持以下SQL特殊形式:
特殊形式 | 相当于 |
---|---|
AT TIME ZONE | timezone() |
CURRENT_CATALOG | current_catalog() |
COLLATION FOR | pg_collation_for() |
CURRENT_DATE | current_date() |
CURRENT_ROLE | current_user() |
CURRENT_SCHEMA | current_schema() |
CURRENT_TIMESTAMP | current_timestamp() |
CURRENT_USER | current_user() |
EXTRACT(<part> FROM <value>) | extract("<part>", <value>) |
OVERLAY(<text1> PLACING <text2> FROM <int1> FOR <int2>) | overlay(<text1>, <text2>, <int1>, <int2>) |
OVERLAY(<text1> PLACING <text2> FROM <int>) | overlay(<text1>, <text2>, <int>) |
SESSION_USER | current_user() |
SUBSTRING(<text> FOR <int1> FROM <int2>)) | substring(<text>, <int2>, <int1>) |
SUBSTRING(<text> FOR <int>) | substring(<text>, 1, <int>)) |
SUBSTRING(<text> FROM <int1> FOR <int2>) | substring(<text>, <int1>, <int2>) |
SUBSTRING(<text> FROM <int>) | substring(<text>, <int>) |
TRIM(<text1> FROM <text2>) | btrim(<text2>, <text1>) |
TRIM(<text2>, <text1>) | btrim(<text2>, <text1>) |
TRIM(FROM <text>) | btrim(<text>) |
TRIM(LEADING <text1> FROM <text2>) | ltrim(<text2>, <text1>) |
TRIM(LEADING FROM <text> ) | ltrim(<text>) |
TRIM(TRAILING <text1> FROM <text2>) | rtrim(<text2>, <text1>) |
TRIM(TRAILING FROM<text> ) | rtrim(<text>) |
USER | current_user() |
例如,如果名称A引用了一个包含 10个值的数组,A[5]则将检索第5个值。第一个值的索引为 1。
如果索引小于或等于 0,或者大于数组的大小,则下标表达式的结果为NULL
。
表达式可以测试条件表达式,并根据是否满足或满足哪个条件,计算一个或多个附加操作数。
这些表达式格式共享以下属性:它们的某些操作数仅在条件为真时才被评估。当操作数否则无效时,这一点尤其重要。例如, 如果a为 0,IF(a=0, 0, x/a)
则返回 0 ,否则返回x/a的值。
语法:
IF ( <cond>, <expr1>, <expr2> )
select IF(tb.a=0, 0, b/a) from tb;
if
--------------------------
0
0
0.33333333333333333333
0.25
语法:
CASE <cond>
WHEN <condval1> THEN <expr1>
[ WHEN <condvalx> THEN <exprx> ] ...
[ ELSE <expr2> ]
END
例如:
select
b,
case b
when 1 then 10
when 2 then 20
when 3 then 30
else null
end as t
from tb;
b | t
-------+-----
0 | NULL
0 | NULL
1 | 10
1 | 10
CASE WHEN <cond1> THEN <expr1>
[ WHEN <cond2> THEN <expr2> ] ...
[ ELSE <expr> ]
END
例如:
select
b,
case
when b=1 then 10
when b=2 then 20
when b=3 then 30
else null
end as t
from tb;
b | t
-------+-----
0 | NULL
0 | NULL
1 | 10
1 | 10
语法:
NULLIF ( <expr1>, <expr2> )
相当于:IF ( <expr1> = <expr2>, NULL, <expr1> )
例如:
select b,c,nullif(b,c) from tb;
b | c | nullif
-------+------+---------
0 | 0 | NULL
0 | 1 | 0
1 | 0 | 1
1 | 1 | NULL
语法:
IFNULL ( <expr1>, <expr2> )
COALESCE ( <expr1> [, <expr2> [, <expr3> ] ...] )
COALESCE
首先计算第一个表达式。如果它的值不是 NULL
,则直接返回它的值。否则,它返回COALESCE
对剩余表达式应用的结果。如果所有表达式都是NULL
,则返回NULL
。
IFNULL(a, b)
相当于COALESCE(a, b)
。
例如:
select c,b, IFNULL(c,b) from tb;
c | b | coalesce
-------+------+-----------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 0
1 | 1 | 1
0 | NULL | 0
1 | NULL | 1
NULL | NULL | NULL
语法:
NOT <expr>
<expr1> AND <expr2>
<expr1> OR <expr2>
AND
和OR
是可交换的。此外,输入AND
和OR
不以任何特定顺序进行评估。如果仅使用另一个操作数就可以完全确定结果,则某些操作数甚至可能根本不求值。
聚合表达式的语法与函数调用相同,但有一个特殊情况COUNT
:
<name> ( <arguments...> )
COUNT ( * )
聚合表达式和函数调用的区别在于前者使用聚合函数 ,并且只能出现在SELECT
子句中呈现的表达式列表中。
聚合表达式根据使用的聚合函数计算当前选定的所有行的组合值。
语法:
<expr> :: <type>
CAST (<expr> AS <type>)
计算表达式并将结果值转换为指定的类型。
例如:
select now(),CAST(now() AS DATE);
now | now
+----------------------------------+---------------------------+
2022-08-09 09:27:21.158674+08:00 | 2022-08-09 00:00:00+00:00
语法:
ARRAY[ <expr>, <expr>, ... ]
计算为包含指定值的数组。
例如:
select ARRAY[6,5,1] AS a;
a
-----------
{6,5,1}
数组的数据类型是从提供的表达式的值推断出来的。数组中的所有位置必须具有相同的数据类型。
语法:
(<expr>, <expr>, ...)
ROW (<expr>, <expr>, ...)
计算一个包含所提供表达式的值的元组。
例如:
select ('a', 13, 2.1) as a;
a
----------------
(a,13,2.1)
结果元组的数据类型是从值中推断出来的,元组中的每个位置都可以具有不同的数据类型。