因为 SQLite 有时会对random()
出现在子查询中的函数进行多次评估,这可能是一个错误,例如:
select op, op from (select abs(random())%10 as op from (select 1));
3|1
Run Code Online (Sandbox Code Playgroud)
我需要一种简单的方法来强制 SQLite 实现子查询,以便random()
只计算一次
这是演示的简化示例 - 我的真实世界查询没有from (select 1)
但从视图中选择
来自 SQLite文档(我的重点):
当子查询出现在语句的
FROM
子句中时,它们也可能需要具体化SELECT
。例如:Run Code Online (Sandbox Code Playgroud)SELECT * FROM ex1 JOIN (SELECT b FROM ex2) AS t ON t.b=ex1.a;
根据查询,SQLite 可能需要将
(SELECT b FROM ex2)
子查询具体化为临时表,然后在 ex1 和临时表之间执行连接。查询优化器试图通过“扁平化”查询来避免这种情况。在前面的示例中,查询可以被展平,SQLite 会自动将查询转换为Run Code Online (Sandbox Code Playgroud)SELECT ex1.*, ex2.b FROM ex1 JOIN ex2 ON ex2.b=ex1.a;
更复杂的查询可能会也可能不会使用查询扁平化来避免临时表。是否所述查询可以展平取决于这些因素,如是否将子查询或外部查询包含聚合函数,
ORDER BY
或GROUP BY
条款,LIMIT
条款,等等。查询何时不能展平的规则非常复杂,超出了本文档的范围。
您也许可以使用 view解决该问题,但似乎至少在这种情况下,添加一个虚拟union
对象足以防止“变平”:
select op, op
from (select abs(random())%10 as op from (select 1) union all select 1 where 1=2);
6|6
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4074 次 |
最近记录: |