我会请求帮助,以了解来自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子句 - 这两个查询都是由w.r.t动态生成的。列,标准,安全性等 此外,上述查询本身可以在另一个查询中用作子查询。 总之,原理是动态生成的视图,以后可以重用。一些查询也可能将多达10-12个这样的动态视图合并在一起。 问题是应用程序应该与数据库无关,至少就PG,Oracle和Oracle而言。 DB2是关注的,一个不支持的功能根本没有实现。
答案 0 :(得分:4)
是的,您可以在Oracle的子查询中使用CTE。来自Oracle 11g docs:
您可以在任何顶级SELECT语句中指定此子句 大多数类型的子查询。查询名称对主查询可见 以及所有后续子查询。对于递归子查询因子分解, 查询名称甚至对定义查询的子查询可见 自称。
例如,这适用于Oracle:
SELECT a.*, b.*
FROM (WITH aa AS
(
SELECT LEVEL l1, mod(level, 5) m1 FROM dual CONNECT BY LEVEL < 50
)
SELECT * FROM aa WHERE m1 < 3) a LEFT JOIN
(WITH bb AS
(
SELECT LEVEL l2, mod(level, 5) m2 FROM dual CONNECT BY LEVEL < 50
)
SELECT * FROM bb WHERE m2 BETWEEN 1 AND 4) b
ON a.l1 = b.l2;
答案 1 :(得分:3)
这不是你问题的直接答案,但也许你可以考虑一下:
SQL Server似乎限制了SQL的语义(不一定是语法),这样做才有意义。例如,如果您还没有指定ORDER BY
子句,则不能使用带有TOP n
子句的子查询。这是有道理的,因为有序子查询是没有意义的,除非它们有限制。其他RDBMS允许这种无意义。
在你的情况下(这只是一个猜测),在子查询中使用CTE只是有限的意义,因为你可以用CTE在最顶层声明的方式重写你的整个查询。你唯一的区别就是每个声明的范围和可读性。
另一方面,CTE允许递归查询,当在子查询中声明CTE时,这可能很难应用......
由于您需要实现与数据库无关的SQL,我建议您不要大量使用CTE。如果CTE很简单,你总是可以将它们重写为简单的视图......
答案 2 :(得分:0)
较新的Microsoft SQL Server版本支持CTE。
答案 3 :(得分:0)
虽然PostgreSQL支持CTE,但它们是一个优化障碍,可防止谓词或连接推入CTE查询。这使得它们在很多情况下不如简单的子查询有效。