子查询中的公共表表达式
我请求帮助了解 Oracle、DB2、Sybase 中的所有 RDBMS 都支持子查询中的公共表表达式 (CTE)。我知道 PostgreSQL 可以,而 MS SQL Server 则不能。
SELECT a.*, b.*
FROM (WHERE aa as (
<<select_query>),
SELECT *
FROM aa
WHERE <<criteria>>
) as a
LEFT JOIN (
WITH bb as (
<<select_query>
),
select * from bb inner join tbl_c on <<innerjoin>> where <<criteria>>
) as b
on <<join_expr>>
我无法在子查询之外定义 with 子句 - 这两个查询都是动态生成的列、条件、安全性等。 另外,上述查询本身可以作为子查询在另一个查询中使用。 总结一下,原理就是动态生成视图,以后可以重复使用。某些查询可能还会将多达 10-12 个这样的动态视图合并在一起。 问题是应用程序应该与数据库无关,至少就 PG、Oracle 和 SQL 而言。对于 DB2 而言,不支持的功能根本不会实现。
I would request for help in understanding which all RDBMS from Oracle, DB2, Sybase support a common table expression (CTE) in a sub-query. I am aware that PostgreSQL does while MS SQL Server does not.
SELECT a.*, b.*
FROM (WHERE aa as (
<<select_query>),
SELECT *
FROM aa
WHERE <<criteria>>
) as a
LEFT JOIN (
WITH bb as (
<<select_query>
),
select * from bb inner join tbl_c on <<innerjoin>> where <<criteria>>
) as b
on <<join_expr>>
I am unable to define the with clause outside the sub-queries - both the queries are dynamically generated w.r.t. the columns, criteria, security, etc.
Also, the above query itself may be used in another query as a sub-query.
In summary, the principle is dynamically generated views, re-usable later. Some queries may have upto 10-12 such dynamic views being merged together as well.
The problem is that the application is supposed to be database-agnostic at least so far as PG, Oracle & DB2 are concerned and features not supported by one are not implemented at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,您可以在 Oracle 的子查询中使用 CTE。来自 Oracle 11g 文档:
例如,这在 Oracle 中有效:
Yes, you can use CTE's in subqueries in Oracle. From the Oracle 11g docs:
As an example, this works in Oracle:
这并不是直接回答你的问题,但也许你可以考虑一下:
SQL Server 似乎限制了 SQL 的语义(不一定是语法),这样做是有意义的。例如,如果您没有指定
TOP n
子句,则子查询不能包含ORDER BY
子句。这是有道理的,因为除非有限制,否则有序子查询是没有意义的。其他 RDBMS 允许这种毫无意义的情况。在您的情况下(这只是猜测),在子查询中使用 CTE 的意义有限,因为您可以以在最顶层声明 CTE 的方式重写整个查询。唯一的区别是每个声明的范围以及可能的可读性。
另一方面,CTE 允许递归查询,当在子查询中声明 CTE 时,这可能很难应用...
由于您需要实现与数据库无关的 SQL,因此我建议您暂时不要大量使用 CTE。如果 CTE 很简单,您始终可以将它们重写为简单视图......
That's not directly an answer to your question, but maybe you can think about this:
SQL Server seems to limit the semantics (not necessarily the syntax) of SQL where it makes sense to do so. For instance, you cannot have a subquery with an
ORDER BY
clause, if you don't also specify aTOP n
clause. This makes sense, as ordered subqueries are pointless unless they have limits. Other RDBMS allow for such pointlessness.In your case (that's just a guess), having CTE's in subqueries only makes limited sense, because you can rewrite your whole query in a way that the CTE's are declared at the top-most level. The only difference you'll have is the scope and maybe the readability of each declaration.
On the other hand, CTE's allow for recursive queries, which might be very hard to apply when CTE's are declared in subqueries...
Since you need to implement database-agnostic SQL, I recommend you do not make heavy use of CTE's yet. If CTE's are simple, you can always rewrite them as simple views...
较新的 Microsoft SQL Server 版本确实支持 CTE。
The newer Microsoft SQL Server versions do support CTE's.
虽然 PostgreSQL 支持 CTE,但它们是一个优化障碍,阻止将谓词或连接推送到 CTE 查询中。这使得它们在许多情况下不如简单子查询有效。
While PostgreSQL supports CTE's, they are an optimisation barrier which prevents predicate or join pushing into the CTE query. This makes them less effective in many cases than a simple subquery.