因为 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 次 |
| 最近记录: |