SELECT
查询执行数据检索。 默认情况下,请求的数据返回给客户端,同时结合 INSERT INTO
可以被转发到不同的表。
[WITH expr_list|(subquery)] SELECT [DISTINCT] expr_list [FROM [db.]table | (subquery) | table_function] [FINAL] [SAMPLE sample_coeff] [ARRAY JOIN ...] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>) [PREWHERE expr] [WHERE expr] [GROUP BY expr_list] [WITH TOTALS] [HAVING expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [LIMIT [offset_value, ]n BY columns] [LIMIT [n, ]m] [WITH TIES] [UNION ALL ...] [settingsClause] [INTO OUTFILE filename] [FORMAT format]
所有子句都是可选的,但紧接在 SELECT
后面的必需表达式列表除外。
SELECT [DISTINCT] expr_list
DISTINCT,查询结果中仅保留唯一的行。它将 NULL 视为一个特定的值,并且 NULL==NULL。
星号符号 (*),星号可以放在查询中的任何部分,代替表达式。当分析查询时,星号会扩展为所有表列的列表(不包括 MATERIALIZED 和 ALIAS 列)。
您可以在查询的任何部分使用同义词 (AS
别名)。
在结果中包含所有列,请使用星号 (*
)符号。 例如, SELECT * FROM ...
.
将结果中包含'a'的列,可以使用 COLUMNS
表达。
示例:
CREATE TABLE sample.col_names (aa Int8, ab Int8, bc Int8) ENGINE = CnchMergeTree order by aa;
以下查询所有列名包含 a
。
SELECT COLUMNS('a') FROM sample.col_names
┌─aa─┬─ab─┐ │ 1 │ 1 │ └────┴────┘
使用多个 COLUMNS
表达式并将函数应用于它们。
示例
SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM sample.col_names
┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ │ 1 │ 1 │ 1 │ Int8 │ └────┴────┴────┴────────────────┘
返回的每一列 COLUMNS
表达式作为单独的参数传递给函数。 如果函数支持其他参数,您也可以将其他参数传递给函数。
说明
注意:使用函数时要小心,如果函数不支持传递给它的参数,ByteHouse将抛出异常。
例如:
SELECT COLUMNS('a') + COLUMNS('c') FROM sample.col_names
Code: 42, Error: DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2 SQLSTATE: 42000
该示例中, COLUMNS('a')
返回两列: aa
和 ab
. COLUMNS('c')
返回 bc
列。 该 +
运算符不能应用于3个参数,因此ByteHouse抛出一个带有相关消息的异常。
匹配的列 COLUMNS
表达式可以具有不同的数据类型。 如果 COLUMNS
不匹配任何列,并且是在 SELECT
唯一的表达式,ClickHouse则抛出异常。
您可以在查询的任何部分使用星号替代表达式。进行查询分析、时,星号将展开为所有表的列(不包括 MATERIALIZED
和 ALIAS
列)。 只有少数情况下使用星号是合理的:
创建转储表时。
对于只包含几列的表,例如系统表。
获取表中列的信息。 在这种情况下,设置 LIMIT 1
. 但最好使用 DESC TABLE
查询。
当对少量列使用 PREWHERE
进行强过滤时。
在子查询中(因为外部查询不需要的列从子查询中排除)。
在所有其他情况下,我们不建议使用星号,因为它只给你一个列DBMS的缺点,而不是优点。 换句话说,不建议使用星号。
如果查询省略 DISTINCT
, GROUP BY
, ORDER BY
, IN
, JOIN
子查询,查询将被完全流处理,使用O(1)量的RAM。 若未指定适当的限制,则查询可能会消耗大量RAM:
max_memory_usage
max_rows_to_group_by
max_rows_to_sort
max_rows_in_distinct
max_bytes_in_distinct
max_rows_in_set
max_bytes_in_set
max_rows_in_join
max_bytes_in_join
max_bytes_before_external_sort
max_bytes_before_external_group_by
本节提供对公共表表达式的支持 (CTE),所以结果 WITH
子句可以在其余部分中使用 SELECT
查询。
Bytehouse 支持公用表表达式(CTE)。WITH 子句的结果可以在后续的 SELECT 查询中使用。对于支持存在一定的限制,包括:
CTE 中不允许递归
CTE 中不允许子查询
语法
WITH [columnExpr] AS identifier
示例1:使用常量表达式作为 “variable”
WITH '2024-07-01 15:23:00' as ts_upper_bound SELECT * FROM system.tables WHERE metadata_modification_time <= ts_upper_bound
示例2:从SELECT子句列表中逐出sum(bytes)表达式结果
WITH sum(total_bytes) as s SELECT formatReadableSize(s), database FROM system.tables GROUP BY database ORDER BY s
示例3:使用标量子查询的结果
/* this example would return TOP 10 of most huge database */ WITH ( SELECT sum(total_bytes) FROM system.tables ) AS total_resoure_size SELECT (sum(total_bytes) / total_resoure_size) * 100 AS db_resource_usage, database FROM system.tables GROUP BY database ORDER BY db_resource_usage DESC LIMIT 10
示例4:在子查询中重用表达式
WITH ['hello'] AS hello SELECT hello, * FROM ( WITH ['hello'] AS hello SELECT hello ) --result ┌─hello─────┬─hello_1─────┐ │ ['hello'] │ ['hello'] │ └───────────┴───────────┘
fromClause 指定了读取数据的来源:
表
子查询
表函数
语法
从表中读取数据
FROM [tableIdentifier] [FINAL] [sampleClause]
从子查询中读取数据
FROM ([selectUnionStmt]) [FINAL] [sampleClause]
从表函数中读取数据
FROM tableFunctionExpr [FINAL] [sampleClause]
FINAL
:当指定 FINAL
时,ByteHouse 在返回结果之前会完全合并数据,因此执行在合并过程中发生的所有数据转换。
示例
CREATE TABLE test.fromClause (id UInt32, val UInt32) ENGINE=CnchMergeTree() ORDER BY id; INSERT INTO test.fromClause VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21); SELECT * FROM test.fromClause; -- expect 5 rows
CREATE TABLE test.fromClause (id UInt32, val UInt32) ENGINE=CnchMergeTree() ORDER BY id; INSERT INTO test.fromClause VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21); SELECT * FROM (SELECT * FROM test.fromClause LIMIT 3); -- expect 3 rows
SELECT * FROM numbers(10); -- expect 10 rows
我们在这里使用表函数 numbers 来生成一个包含 10 行的表。
sampleClause 允许进行近似的 SELECT 查询处理。启用 sampleClause 后,查询不会在所有数据上执行,而只会在某个数据片段上执行。这在以下情况下非常有用:
有严格的时间要求(如小于100毫秒),但无法证明为了满足这些要求而增加硬件资源的成本是合理的。
原始数据不准确,因此近似不会显著降低质量。
业务需求目标是近似结果(为了成本效益,或将精确结果提供给高级用户)。
注意:要使用采样,必须在创建 CnchMergeTree 表时声明采样表达式,详见 [sampleByClause]。
下面列出了数据采样的功能:
数据采样是一种确定性机制。 同样的结果 SELECT .. SAMPLE
查询始终是相同的。
对于不同的表,采样工作始终如一。 对于具有单个采样键的表,具有相同系数的采样总是选择相同的可能数据子集。 例如,用户Id的示例采用来自不同表的所有可能的用户Id的相同子集的行。 这意味着您可以在子查询中使用采样 IN 此外,您可以使用 JOIN 。
采样允许从磁盘读取更少的数据。 请注意,您必须正确指定采样键。
为 SAMPLE
子句支持以下语法:
SAMPLE Clause Syntax | 产品描述 |
---|---|
SAMPLE k | 这里 k 是从0到1的数字。 |
SAMPLE n | 这里 n 是足够大的整数。 |
SAMPLE k OFFSET m | 这里 k 和 m 是从0到1的数字。 |
这里 k
从0到1的数字(支持小数和小数表示法)。 例如, SAMPLE 1/2
或 SAMPLE 0.5
.
语法
SAMPLE K
示例
在此示例中,将使用10%的数据进行近似计算。
CREATE TABLE IF NOT EXISTS test.sampleClause (id UInt32) ENGINE=CnchMergeTree ORDER BY id SAMPLE BY id; INSERT INTO test.sampleClause SELECT * FROM numbers(1000); SELECT COUNT() FROM test.sampleClause SAMPLE 0.1; -- 1000 is expected
这里 n
是足够大的整数。 例如, SAMPLE 10000000
.
在这种情况下,查询在至少一个样本上执行 n
行(但不超过这个)。 例如, SAMPLE 10000000
在至少10,000,000行上运行查询。
语法
SAMPLE N
示例
在此示例中,将使用2行数据进行近似计算。
CREATE TABLE IF NOT EXISTS test.sampleClause (id UInt32) ENGINE=CnchMergeTree ORDER BY id SAMPLE BY id; INSERT INTO test.sampleClause SELECT * FROM numbers(1000); SELECT COUNT() FROM test.sampleClause SAMPLE 2; -- 1000 is expected
这里 k
从0到1的数字(支持小数和小数表示法)。 例如, SAMPLE 1/2
或 SAMPLE 0.5
.
语法
SAMPLE K OFFSET M
示例
在此示例中,跳过20%的数据后,将使用10%的数据进行近似计算。
CREATE TABLE IF NOT EXISTS test.sampleClause (id UInt32) ENGINE=CnchMergeTree ORDER BY id SAMPLE BY id; INSERT INTO test.sampleClause SELECT * FROM numbers(1000); SELECT COUNT() FROM test.sampleClause SAMPLE 0.1 OFFSET 0.2;
Join 通过使用每个表中共有的值,将一个或多个表的列组合在一起生成一个新表。
语法
[ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN [tableIdentifier] ON|USING [columnExprList]
[ANY|ALL|ASOF]:
ANY:如果右表有多行匹配,则只连接找到的第一行。如果右表只有一行匹配,ANY 和 ALL 的结果相同。
ALL:如果右表有多行匹配,ClickHouse 会从匹配的行中创建一个笛卡尔积。这是标准 SQL 中的正常 JOIN 行为。
ASOF:用于连接具有不确定匹配的序列。
[INNER|LEFT|RIGHT|FULL|CROSS]:所有标准 SQL JOIN 类型。
INNER JOIN:只返回匹配的行。
LEFT OUTER JOIN:除了返回匹配的行,还返回左表中不匹配的行。
RIGHT OUTER JOIN:除了返回匹配的行,还返回右表中不匹配的行。
FULL OUTER JOIN:除了返回匹配的行,还返回两个表中不匹配的行。
CROSS JOIN:生成整个表的笛卡尔积,不指定“连接键”。
ON|USING:
ON 子句中的表达式和 USING 子句中的列被称为“连接键”。
示例
CREATE TABLE IF NOT EXISTS test.joinClause (number UInt64) ENGINE=CnchMergeTree ORDER BY number; INSERT INTO test.joinClause SELECT * FROM numbers(10); SELECT number, joined FROM test.joinClause ANY LEFT JOIN (SELECT number * 2 AS number, number * 10 + 1 AS joined FROM test.joinClause LIMIT 10) js2 USING number LIMIT 10
number | joined |
---|---|
0 | 1 |
1 | NULL |
2 | 21 |
3 | NULL |
对于包含数组列的表,数组连接(array join)可以生成一个新表,该新表的列包含初始列中每个单独的数组元素,而其他列的值则会被重复。
语法
[LEFT] ARRAY JOIN [columnExprList]
在一个 SELECT
查询中只能指定一个 arrayJoinClause。[LEFT] ARRAY JOIN
:ARRAY JOIN 的类型
ARRAY JOIN
- 在基础情况下,空数组不会包含在 JOIN
的结果中。
LEFT ARRAY JOIN
- JOIN
的结果包含具有空数组的行。空数组的值被设置为数组元素类型的默认值(通常为 0、空字符串或 NULL)。
示例
CREATE TABLE test.arrayJoinClause(s String, arr Array(UInt8)) ENGINE = CnchMergeTree ORDER BY s; INSERT INTO test.arrayJoinClause VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); SELECT s, arr FROM test.arrayJoinClause ARRAY JOIN arr;
Prewhere 是一种优化,用于更高效地应用过滤。即使未显式指定 PREWHERE 子句,它也默认启用。它通过自动将部分 WHERE 条件移动到 prewhere 阶段来工作。PREWHERE 子句的作用仅在于当你认为自己比默认优化做得更好时,控制这种优化。
使用 prewhere 优化时,首先只读取执行 prewhere 表达式所需的列。然后读取执行查询其余部分所需的其他列,但仅读取那些在某些行中 prewhere 表达式为“true”的数据块。如果有很多数据块在所有行中 prewhere 表达式均为“false”,且 prewhere 需要的列比查询的其他部分少,这通常可以使查询执行时从磁盘读取的数据大大减少。
语法
PREWHERE [columnExpr](http://columnexpr/)
示例
CREATE TABLE test.prewhereClause(id UInt32, val UInt32) ENGINE = CnchMergeTree() ORDER BY id; INSERT INTO test.prewhereClause VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21); SELECT * FROM test.prewhereClause PREWHERE id=1 WHERE val>10; -- (1, 11), (1, 12) expected
WHERE
子句允许过滤来自SELECT
的子句 FROM 的数据.
如果有一个 WHERE
子句,它必须包含一个表达式与 UInt8
类型。 这通常是一个带有比较和逻辑运算符的表达式。 表达式计算结果为0的行将被排除在在进一步的转换或结果之外。
如果基础表引擎支持,WHERE
表达式会使用索引和分区进行剪枝。
语法
WHERE [columnExpr]
示例
CREATE TABLE test.whereClause(id UInt32, val UInt32) ENGINE = CnchMergeTree() ORDER BY id; INSERT INTO test.whereClause VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21); SELECT * FROM test.whereClause WHERE val>10; -- (1, 11), (1, 12), (2, 20), (2, 21) expected
如果需要测试一个 NULL 值,请使用 IS NULL 和 IS NOT NULL 运算符或 isNull 和 isNotNull 函数。否则带有 NULL 的表达式永远不会通过。
示例
CREATE TABLE t_null(x Int8, y Nullable(Int8)) ENGINE=CnchMergeTree() ORDER BY x; INSERT INTO t_null VALUES (1, NULL), (2, 3); SELECT * FROM t_null WHERE y IS NULL; SELECT * FROM t_null WHERE y != 0;
结果
┌─x─┬────y─┐ │ 1 │ ᴺᵁᴸᴸ │ └───┴──────┘ ┌─x─┬─y─┐ │ 2 │ 3 │ └───┴───┘
GROUP BY
子句将 SELECT
查询结果转换为聚合模式。GROUP BY
子句 下的 [columnExprList] 作为分组键,聚合 SELECT
查询的结果将包含与源表中分组键唯一值相同数量的行。
语法
GROUP BY [(][columnExprList][)] [WITH ROLLUP|WITH CUBE] [WITH TOTALS]
NULL processing
:ByteHouse 将 NULL 解释为一个值。如果分组键包含 NULL 值,它将在结果中出现。
[WITH ROLLUP]
:根据GROUP BY
列表中键表达式的顺序计算小计。
* 小计行会添加到结果表之后。
* 在小计行中,已“分组”的键表达式的值将设置为 0 或空行。
[WITH CUBE]
:计算 GROUP BY
列表中键表达式每种组合的小计。
[WITH TOTALS]
:计算 GROUP BY
列表中所有键表达式组合的小计。
示例1:Group by 键 包含 NULL 值.
CREATE TABLE IF NOT EXISTS test.groupByClause (x UInt32, y Nullable(UInt32)) ENGINE=CnchMergeTree ORDER BY x; INSERT INTO test.groupByClause VALUES (1,2),(2,NULL),(3,2),(3,3),(3,NULL); SELECT sum(x), y FROM test.groupByClause GROUP BY y;
示例2:按组汇总的 WITH ROLLUP 修饰符
CREATE TABLE IF NOT EXISTS test.groupByClause (year UInt32, month UInt32, day UInt32) ENGINE=CnchMergeTree ORDER BY year; INSERT INTO test.groupByClause VALUES (2019,1,5),(2019,1,15),(2020,1,5),(2020,1,15),(2021,1,5),(2021,1,15); SELECT year, month, day, count() FROM test.groupByClause GROUP BY year, month, day WITH ROLLUP;
由于 GROUP BY 部分包含三个键表达式,结果包含从右到左汇总的小计表:
GROUP BY year, month, day;
GROUP BY year, month(并且 day 列填充为零);
GROUP BY year(现在 month 和 day 列都填充为零);
总计(所有三个键表达式列都为零)。
示例3:按组汇总的 WITH CUBE 修饰符
CREATE TABLE IF NOT EXISTS test.groupByClause (year UInt32, month UInt32, day UInt32) ENGINE=CnchMergeTree ORDER BY year; INSERT INTO test.groupByClause VALUES (2019,1,5),(2019,1,15),(2020,1,5),(2020,1,15),(2021,1,5),(2021,1,15); SELECT year, month, day, count() FROM test.groupByClause GROUP BY year, month, day WITH CUBE;
由于 GROUP BY 部分包含三个键表达式,结果包含八个小计表,涵盖所有键表达式组合的小计:
GROUP BY year, month, day
GROUP BY year, month
GROUP BY year, day
GROUP BY year
GROUP BY month, day
GROUP BY month
GROUP BY day
总计(所有三个键表达式列都为零)
示例4:按组汇总的 WITH TOTAL 修饰符
CREATE TABLE IF NOT EXISTS test.groupByClause (year UInt32, month UInt32, day UInt32) ENGINE=CnchMergeTree ORDER BY year; INSERT INTO test.groupByClause VALUES (2019,1,5),(2019,1,15),(2020,1,5),(2020,1,15),(2021,1,5),(2021,1,15); SELECT year, month, day, count() FROM test.groupByClause GROUP BY year, month, day WITH TOTALS;
如果指定了 WITH TOTALS 修饰符,将会计算另一行。
为每个表达式的不同值选择前 m 行
语法
为每个列表达式的不同值从结果中选择前 m 行。
LIMIT m BY [columnExprList]
示例:按列表达式限制 m 行
CREATE TABLE test.limitByClause(id UInt32, val UInt32) ENGINE = CnchMergeTree() order by id; INSERT INTO test.limitByClause VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21); SELECT * FROM test.limitByClause ORDER BY id, val LIMIT 2 BY id; -- expect 4 rows. (1, 10), (1, 11), (2, 20), (2, 21)
在此示例中,对于每个 id(包括值 1 和 2),我们需要返回 2 行。
过滤由 groupByClause 生成的聚合结果。它类似于 whereClause,但区别在于 WHERE 在聚合之前执行,而 HAVING 在聚合之后执行。
语法
HAVING [columnExpr](http://columnexpr/)
示例
CREATE TABLE test.havingClause(id UInt32, val UInt32) ENGINE = CnchMergeTree() ORDER BY id; INSERT INTO test.havingClause VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21); SELECT id FROM test.havingClause GROUP BY id HAVING count(id)>2; -- only 1 is expected.
如果 SELECT DISTINCT
被声明,则查询结果中只保留唯一行。 因此,在结果中所有完全匹配的行集合中,只有一行被保留。
空处理DISTINCT
适用于 NULL 就好像 NULL
是一个特定的值,并且 NULL==NULL
. 换句话说,在 DISTINCT
结果,不同的组合 NULL
仅发生一次。 它不同于 NULL
在大多数其他情况中的处理方式。
替代办法
通过应用可以获得相同的结果 GROUP BY 在同一组值指定为 SELECT
子句,并且不使用任何聚合函数。 但与 GROUP BY
有几个不同的地方:
DISTINCT
可以与 GROUP BY
一起使用.注意
DISTINCT
不支持当SELECT
包含有数组的列。
示例
ByteHouse支持使用 DISTINCT
和 ORDER BY
在一个查询中的不同的列。 DISTINCT
子句在 ORDER BY
子句前被执行。
示例表:
┌─a─┬─b─┐ │ 2 │ 1 │ │ 1 │ 2 │ │ 3 │ 3 │ │ 2 │ 4 │ └───┴───┘
当执行 SELECT DISTINCT a FROM t1 ORDER BY b ASC
来查询数据,我们得到以下结果:
┌─a─┐ │ 2 │ │ 1 │ │ 3 │ └───┘
如果我们改变排序方向 SELECT DISTINCT a FROM t1 ORDER BY b DESC
,我们得到以下结果:
┌─a─┐ │ 3 │ │ 1 │ │ 2 │ └───┘
行 2, 4
排序前被切割。
LIMIT m
允许选择结果中起始的 m
行。LIMIT n, m
允许选择个 m
从跳过第一个结果后的行 n
行。 与 LIMIT m OFFSET n
语法是等效的。n
和 m
必须是非负整数。
如果没有 ORDER BY 子句显式排序结果,结果的行选择可能是任意的和非确定性的。
语法
LIMIT m LIMIT n, m LIMIT m OFFSET n LIMIT ... WITH TIES
示例1:LIMIT m
CREATE TABLE IF NOT EXISTS test.limitClause (id UInt32) engine=CnchMergeTree() order by id; INSERT INTO test.limitClause VALUES (1),(2),(3),(4),(5); SELECT * FROM test.limitClause LIMIT 2; -- first 2 values will be return
示例2:LIMIT n, m
CREATE TABLE IF NOT EXISTS test.limitClause (id UInt32) engine=CnchMergeTree() order by id; INSERT INTO test.limitClause VALUES (1),(2),(3),(4),(5); SELECT * FROM test.limitClause LIMIT 1,2; -- skip first value,next 2 values will be return SELECT * FROM test.limitClause LIMIT 2 OFFSET 1; -- skip first value,next 2 values will be return
示例3:LIMIT ... WITH TIES
SELECT * FROM ( SELECT number%50 AS n FROM numbers(100) ) ORDER BY n LIMIT 0,5 WITH TIES ┌─n─┐ │ 0 │ │ 0 │ │ 1 │ │ 1 │ │ 2 │ │ 2 │ └───┘
你可以使用 UNION ALL
结合任意数量的 SELECT
来扩展其结果。
语法
UNION ALL ...
示例
SELECT CounterID, 1 AS table, toInt64(count()) AS c FROM test.hits GROUP BY CounterID UNION ALL SELECT CounterID, 2 AS table, sum(Sign) AS c FROM test.visits GROUP BY CounterID HAVING c > 0
结果列通过它们的索引进行匹配(在内部的顺序 SELECT
). 如果列名称不匹配,则从第一个查询中获取最终结果的名称。对联合执行类型转换。
例如,如果合并的两个查询具有相同的字段与非-Nullable
和 Nullable
从兼容类型的类型,由此产生的 UNION ALL
有一个 Nullable
类型字段。
属于以下部分的查询 UNION ALL
不能用圆括号括起来。 ORDER BY 和 LIMIT 应用于单独的查询,而不是最终结果。 如果您需要将转换应用于最终结果,则可以将所有查询 UNION ALL
在子查询中 FROM 子句。
说明
限制:只有 UNION ALL
支持。 UNION
(UNION DISTINCT
)不支持。 如果你需要 UNION DISTINCT
,你可以写 SELECT DISTINCT
子查询中包含 UNION ALL
.
语法
SETTINGS [settingExprList]
添加 INTO OUTFILE filename
子句(其中filename是字符串) SELECT query
将其输出重定向到客户端上的指定文件。
语法
[INTO OUTFILE filename]
示例
select * from ttt into outfile '~/abc.txt'
- 此功能是在可用 命令行客户端 和 clickhouse-local. 因此通过 HTTP接口 发送查询将会失败。
- 如果具有相同文件名的文件已经存在,则查询将失败。
- 默认值 输出格式 是
TabSeparated
(就像在命令行客户端批处理模式中一样)。
ByteHouse支持 序列化格式 可用于查询结果。 有多种方法可以选择格式化 SELECT
的输出,其中之一是指定 FORMAT format
在查询结束时以任何特定格式获取结果集。
语法
FORMAT format