Skip to content

Select 查询

SELECT 从数据库中获取期望的数据

语法

sql
SELECT 
 [DISTINCT]
 select_expr [, select_expr] ...
[FROM table_expr]
[WHERE where_condition]
[GROUP BY <col_name | expr>[, column_name | expr]]
[HAVING where_condition]
[ORDER BY <col_name | expr>] [ASC | DESC]
[LIMIT <[offset, ] row_count | row_count OFFSET offset>]

DISTINCT

从结果集中去除重复的行。DISTINCT 的作用域是整个 select_expr...

select_expr

输出的字段,至少需要一个 select_expr, 支持列表如下:

  • 常量:1/2.1/true
  • 函数:now()/max()/min()/from_unixtime()/count()...
  • 列名:columnName...
  • 计算表达式:columnA + columnB..., 支持 加+, 减-, 乘*, 除/, 取余%
    • 表达式:查询所有字段
  • 数组:(1,2,3)
  • 二元表达式:-1, -columnName
  • null: NULL
  • CASE WHEN 表达式
    • CASE value WHEN condition THEN result [WHEN condition THEN result ...] [ELSE result] END
    • CASE WHEN condition THEN result [WHEN condition THEN result ...] [ELSE result] END
  • 比较表达式:返回值为 bool 类型
    • 2 > 1: 返回 true
    • a REGEXP b

可添加别名 AS, 支持的函数及文档见函数

table_expr

需要查询的表,支持:

  • simple table
    SELECT ... FROM a

  • join table
    SELECT ... FROM a JOIN b ON ...

  • derived table
    SELECT ... FROM (SELECT ... FROM a) tableAlias

  • dual table/empty table
    SELECT now(), curdate(), 1 + 1 ... [FROM dual]

    结果为一行

where 条件

  • Comparison expr(比较表达式)
    a [ > | < | <> | >= | <= | != | = | LIKE | NOT LIKE | REGEXP | RLIKE | NOT RLIKE | NOT REGEXP | IN | NOT IN ] b

  • columnName = 'abc'

  • columnName [NOT] LIKE '%abc%'

  • columnName [NOT] REGEXP '^.abc.$'

  • columnName [NOT] RLIKE '^.abc.$'

  • columnName [NOT] IN ('abc', 'def')

  • IS expr(IS 表达式)
    IS true | IS NOT true | IS false | IS NOT false | IS NULL | IS NOT NULL

  • columnName IS [NOT] true/false

  • columnName IS [NOT] NULL

  • Bool expr(Boolean 表达式)
    true | false

  • AND expr(逻辑与表达式)

  • columnNameA = 'abc' AND columnNameB = 'def'

  • OR expr(逻辑或表达式)

  • columnNameA = 'abc' OR columnNameB = 'def'

  • concat('...', ...) = '...'

    WHERE 子句中仅可使用除开聚合函数外的其他函数

REGEXP 中使用的正则表达式语法可参考 Regular Expressions Syntax

数据库会根据表结构中的类型推导进行计算过滤,对于以下 WHERE 条件,数据库也能得到正确的结果。

int32_column > '100'

对于 string_column > 100 则会将 string_column 转为 float,与 100 进行比较,如果转换失败则会使用 0100 进行比较。

GROUP BY

对结果集进行分组

  • col_names: 按列的值进行分组
  • aggregate_window: 对时间列进行窗口切分分组
  • interval: interval(time_column, every) 同 aggregate_window(time_column, every, true)

HAVING

对结果集进行过滤,与 WHERE 类似,但是与 WHERE 不同的是:

  • WHERE 过滤进行在分组之前,HAVING 过滤进行在分组之后

使用 HAVING 需遵守以下规则:

  1. 如果 HAVING 上游是一个聚合查询(select_exprs 里面有聚合函数或者 select 语句里面有 GROUP BY),则仅可使用子句为聚合函数或聚合函数别名的 HAVING,且不管 HAVING 子句是否存在于 select_exprs

    • SELECT max(a) as m FROM ... HAVING m > 0

      HAVING 中使用聚合函数别名

    • SELECT max(a) FROM ... HAVING avg(x) > avg(y)

      HAVING 中直接使用聚合函数且不存在于 selectExprs 中

    • SELECT max(a) FROM ... HAVING a > 0

      报错: "unknown column 'a' in having clause"

  2. 如果 HAVING 上游不是一个聚合查询,则 HAVING 退化为 WHERE(不支持聚合函数,且子句必须存在于 select_exprs 中)

    • SELECT a, b, c FROM t1 HAVING c > 0

      将会改写为:SELECT a, b, c FROM t1 WHERE c > 0

    • SELECT a, b, c FROM t1 HAVING max(d) > 0

      报错:"Invalid use of group function"

    • SELECT a, b, c FROM t1 HAVING d > 0

      报错:"Unknown column 'd' in HAVING clause"

ORDER BY

对结果集进行排序,升序 (ASC) 或降序 (DESC) 输出,null 视为最小的值。

  • col_names
  • 函数:rand() ...
  • 表达式:column + 1 ...

可添加多个排序字段:

ORDER BY columnA asc, columnB desc

最终结果为按 columnA 升序,columnB 降序排列,如果 columnA 列其中多行数据相同,则按 columnB 降序输出。

最大有序结果为 500w 条,超出 500w 条的数据不保证顺序。

LIMIT

限制输出条目数

  • LIMIT 100, 10 | LIMIT 10 OFFSET 100: 从第 100 条开始输出,10 条截止。

offset, row_count 必须为非负数,可以为:

  • 整数 (1,2...)
  • 十六进制数 (0x01,0x02...)
  • 十六进制字符串 (X'31')
  • 二进制字符串 (B'10')

结果集数据类型

结果集中的数据类型会依据表定义(DDL)的类型进行输出,会输出在最新版本的表结构中的类型。

如果输入的 SQL 中含有计算表达式则会根据需要计算的表达式类型推导输出类型

例如:

  • int(8/16/32/64) + int(8/16/32/64) 输出结果中的类型为 int64,
    • 当计算结果超出 int64 能表达的最大或最小值 ([-2^63, 2^63-1]) 时,会报错
    • 前 N 行计算结果未溢出,第 N 行计算结果溢出时,将会返回前 N 行后报错
  • float(32/64) * float(32/64) 输出结果中的类型为 float64
    • 当计算结果超出 float64 能表达的最大或最小值 ([-1.79769e+308, 1.79769e+308]) 时,会报错
    • 前 N 行计算结果未溢出,第 N 行计算结果溢出时,将会返回前 N 行后报错
  • 2 > 1/true/false 输出结果中的类型为 int64(1: true, 0: false)
  • 当输出结果为 NaN(Not a Number), ±Inf(Infinite) 时,输出 NULL

聚合函数

查询结果中的列名

在返回查询结果的时候,SELECT 语句中的 * 会展开为对应的表中的所有列。对于其他表达式,会使用表达式本身作为列名。如果表达式包含 AS 子句,则使用 AS 子句中的别名作为列名。(大小写会与用户输入保持一致,且不会插入特殊字符)

Union 查询

    (selectStmtA) 
UNION [ALL] 
    (selectStmtB)
[
UNION [ALL] 
    (selectStmtC)
]
[ORDER BY ...]
[LIMIT ...]

将 selectStmtB 的结果集添加到 selectStmtA 结果集之后,并将结果集去重,selectStmtA 与 selectStmtB 以及更多需要 union 的查询输出字段个数需一致

当使用 UNION ALL 时,不会将结果集去重

输出

输出字段为 selectStmtA 的结果集字段名称,字段类型为所有查询相同位置的列的最大类型:

    (SELECT int8, int16 FROM ...)
UNION
    (SELECT int64, float64 FROM ...)

结果集的字段为:int8, int16,类型为:VtInt64, VtFloat64