以下语法起作用的可能原因是什么:
SELECT SUM(*), AVG(*), MIN(*), MAX(*), ANY_VALUE(*);
输出:
总和(*) | 平均值(*) | 最小(*) | 最大(*) | 任意_值(*) |
---|---|---|---|---|
空 | 空 | 空 | 空 | 空 |
数据类型:
DESCRIBE RESULT LAST_QUERY_ID();
/*
name type kind
SUM(*) NUMBER(30,0) COLUMN
AVG(*) NUMBER(36,6) COLUMN
MIN(*) VARCHAR(0) COLUMN
MAX(*) VARCHAR(0) COLUMN
ANY_VALUE(*) VARCHAR(0) COLUMN
*/
根据查询配置文件,解析为:
EXPLAIN USING TABULAR
SELECT SUM(*), AVG(*), MIN(*), MAX(*), ANY_VALUE(*);
提供表/子查询时
*
被解析为第一列:
SELECT SUM(*), AVG(*), MIN(*), MAX(*), ANY_VALUE(*)
FROM (VALUES (1)) sub(c);
/*
SUM(*) AVG(*) MIN(*) MAX(*) ANY_VALUE(*)
1 1 1 1 1
*/
但是,如果存在多于一列,则不起作用:
SELECT SUM(*), AVG(*), MIN(*), MAX(*), ANY_VALUE(*)
FROM (VALUES (1,2));
错误:函数 [SUM(VALUES.COLUMN1, VALUES.COLUMN2)] 的参数太多
还有:
SELECT SUM(*)
FROM (VALUES(1))
HAVING SUM(*) > 1;
仅在 SELECT 子句中允许使用 * 作为函数参数。
聚合函数的文档没有为
*
在 SUM、MIN/MAX 等上下文中提供任何线索。
我正在寻找可能有用的有效用例。
编辑:
接受多个单一输入的聚合函数:
SELECT LISTAGG(*) FROM (SELECT 'a', 'b');
--error: argument 2 to function LISTAGG needs to be constant, found'"values"."'B'"'
但是:
SELECT MIN_BY(*)
FROM (VALUES('a', 'b'), ('aa', 'a')) AS sub(c1, c2);
/*
MIN_BY(*)
aa
*/
我的假设是它是来自
count(*)
的“魔法神器”,这确实是一个奇怪的表达。
是的,又不是。但考虑到解析器会看到
<inbuilt_built_function(token)><paren><star><paren>
和 count
是一个内置函数,其他函数也是如此。我认为 * 将充当“将所有输入放在这里”的模板。应该可以使用 count(distinct *)
进行测试,给出与 count(distinct a,b,c)
相同的结果(对于三列表)
因此,* 到“所有输入”的扩展只是自动魔术化,然后
sum(a,b)
未能通过 sum 的参数计数检查,这不是解析问题,也不是 AST 问题,而是几乎运行-时间问题。
select
count(*) as c1,
count(distinct *) as c2,
count(distinct column1, column2) as c3
from values
(1,2),
(1,2),
(null, null);
好吧,这并没有证明我的想法,但它确实表明标记器正在生成一个开始标记......:-)
select
count(*) as c1,
count(column1) as c2,
count(column2) as c3,
count(column1, column2) as c4,
--count(distinct *) as c2,
--count(distinct(column1, column2)) as c2,
count(distinct column1, column2) as c3
from values
(1,2),
(1,2),
(null, null);
select
count(*) as c1,
count(column1) as c2,
count(column2) as c3,
count(column1, column2) as c4,
count(distinct column1, column2) as c3
from values
(1,2),
(1,2),
(null, null);
啊,是的,* 表示存在一行,作为显式名称,触发非空值,所以它是参数的扩展。但是整个 TYPE 类参数,计数必须理解的“行”,以及 SUM 和 MAX 等,可以处理,但只是自动魔术成“必须只有一列”。
超级弱的答案,因为自动魔法就像免费的午餐,“更好”。
或者它“令人恶心”,但是一些大客户有很多 SQL“无法更改,并且需要支持才能赚大钱,所以嘿为什么不呢?”我不喜欢这些,因为它们看起来太简单并且思维封闭。但它们作为选项而存在。
对于如何在 Medium 上进行 PIVOT 有一个非常好的解释,并且对于源的参数(未在结果列或独立于所选列的输出列中命名),它有一个隐式的
GROUPING BY ALL
,因此已经有一个概念“只要接受你所得到的所有东西,并理解它”就可以支持这一点。也许它就像 C 中的 ARGC、ARGV 或 C# 中的 params,它变成了一桶东西,被动态处理,因此出现 LISTAGG 错误,这确实显示了参数的想法。
这太有趣了!