我的问题是
SQL中的
CTE
和View
有什么区别。我的意思是在哪种情况下我应该使用 CTE
,哪种情况下应该使用 View
。我知道两者都是某种虚拟表,但我无法区分它们的用途。
我发现了一个类似的问题here,但它与性能有关。
更新1:
例如:我有一个充满交易的数据库(
tbl_trade
)。我需要从 350 万条记录中仅选择当月直到当前时间打开的交易,然后操作数据(在虚拟表上使用不同的查询 - 这看起来像视图)。这里的问题是我想要 3-4 列的 SUM
,然后我需要 SUM
一些列并使用结果创建一个虚拟列(看起来像 CTE)。
例如:
tbl_trade
有列:profit
、bonus
和expenses
。
我需要 SUM(profit)
,SUM(bonus)
,SUM(expenses)
和一个新列 total
,它将等于 SUM(profit)
+SUM(bonus)
+SUM(expenses)
。
PS。重新运行
SUM
的查询不是一个选项,因为我已经有了结果。
提前致谢!
视图可以被索引,但 CTE 不能。所以这是很重要的一点。
CTE 在
tree hierarchy
i.e. 上表现出色递归
此外,在处理复杂查询时请考虑视图。视图是数据库上的物理对象(但不物理存储数据),可用于多个查询,从而提供灵活性和集中式方法。另一方面,CTE 是临时的,在使用时会创建;这就是为什么它们被称为
inline view
。
更新
根据您更新的问题,视图将是正确的选择。在 CTE 中处理 350 万行将会给 TempDb 带来额外的开销,最终会降低 SQL Server 的性能。请记住,CTE 是一次性视图,因此不会存储任何统计信息,并且您也无法创建索引。它就像一个子查询。
计划优化器对两者的解释完全相同。这只是不同的事情。
视图可以单独使用。它可以将复杂的语句封装为更简单的查询。
CTE 主要用于编写更清晰的代码,例如过程/视图中冗余较少。您也可以使用 CTE 进行递归查询,这是一个非常伟大且强大的功能!
我希望这有助于澄清事情。
选择CTE的原因之一:如果要做分层查询,就使用CTE。 CTE 可以递归调用。视图不能递归调用。
CTE 仅在查询运行时存在于内存中。查询运行后,CTE被丢弃;除非我们再次定义它,否则它不能用于下一个 SQL 查询。尽管如此,同一个 CTE 可能会在主查询和任何子查询中多次引用。
视图是一个存储的 SQL 查询,每次在另一个查询中引用它时都会执行该查询。请注意,视图不存储特定查询的输出 - 它存储查询本身。
关于 SQL 视图,要记住的关键一点是,与 CTE 相比,视图是数据库中的物理对象,存储在磁盘上。但是,视图仅存储查询,而不存储查询返回的数据。每次您在查询中引用视图时都会计算数据。
再添加一项考虑因素:权限。
CREATE
权限,您可能已被授予也可能未授予这些权限。数据库管理员可能不认同上述内容,因此您可能无法首先创建视图。
在这种情况下,您可以将 CTE 视为一次性视图,它不需要您运行
SELECT
查询所需的更多权限。
我经常使用 CTE 来创建独立且不需要额外维护的东西,尤其是示例代码。
目前,文档对
CTE
说得非常清楚:can be thought of as defining temporary tables that exist just for one query.
参考:https://www.postgresql.org/docs/current/queries-with.html