2014-10-09 71 views
0

我的目标是确定字符串中字符串的重复次数。一个例子是在'abcdabcabcdeab'字符串中重复了多少次'ab'。在一个sql命令中创建测试表

进出口使用Oracle数据库,并已经把这个命令:

with test as (Select 'abcdabcabcdeab' str, 'ab' ab) 
Select str, ab, (length(str) - length(replace (str, ab)))/length(ab); 
from test; 

不要担心整个声明,我的问题是什么“以测试为(选择...)”做吗?

我的猜测是它创建了一个名为test的表,它将以名称Select 'abcdabcabcdeab' str, 'ab' ab显示 - 我不明白with如何创建表?

+5

这是一个通用表格表达式(也称为CTE)。它与from子句中的派生表没有什么不同,只是更容易阅读。 – Andrew 2014-10-09 15:38:10

+0

也称为[subquery factoring](http://docs.oracle.com/cd/E11882_01/server.112/e10592/statements_10002.htm#i2077142)。 – 2014-10-09 15:55:32

回答

0

一般来讲,如果你有一个情况下,我们需要在同一subquery多次重新定义,而是直接使用已定义的查询名称WITH子句,使查询更容易阅读。也许,这就是为什么它被称为subquery factoring

例如,

使用SCOTT模式,为每一位员工,我们想知道其他人有多少是在他们的部门。使用内联视图,我们可以执行以下操作。

SELECT e.ename AS employee_name, 
     dc.dept_count AS emp_dept_count 
FROM emp e, 
     (SELECT deptno, COUNT(*) AS dept_count 
     FROM emp 
     GROUP BY deptno) dc 
WHERE e.deptno = dc.deptno; 

使用WITH子句如下所示。

WITH dept_count AS (
    SELECT deptno, COUNT(*) AS dept_count 
    FROM emp 
    GROUP BY deptno) 
SELECT e.ename AS employee_name, 
     dc.dept_count AS emp_dept_count 
FROM emp e, 
     dept_count dc 
WHERE e.deptno = dc.deptno; 

这里的区别似乎相当微不足道。 如果我们还想撤回每个员工经理姓名和经理部门中的人数,该怎么办?使用内联视图,现在看起来像这样。

SELECT e.ename AS employee_name, 
     dc1.dept_count AS emp_dept_count, 
     m.ename AS manager_name, 
     dc2.dept_count AS mgr_dept_count 
FROM emp e, 
     (SELECT deptno, COUNT(*) AS dept_count 
     FROM emp 
     GROUP BY deptno) dc1, 
     emp m, 
     (SELECT deptno, COUNT(*) AS dept_count 
     FROM emp 
     GROUP BY deptno) dc2 
WHERE e.deptno = dc1.deptno 
AND e.mgr = m.empno 
AND m.deptno = dc2.deptno; 

使用WITH子句,如下所示。

WITH dept_count AS (
    SELECT deptno, COUNT(*) AS dept_count 
    FROM emp 
    GROUP BY deptno) 
SELECT e.ename AS employee_name, 
     dc1.dept_count AS emp_dept_count, 
     m.ename AS manager_name, 
     dc2.dept_count AS mgr_dept_count 
FROM emp e, 
     dept_count dc1, 
     emp m, 
     dept_count dc2 
WHERE e.deptno = dc1.deptno 
AND e.mgr = m.empno 
AND m.deptno = dc2.deptno; 

因此,底线是,我们不需要多次重新定义相同的子查询。相反,我们只需使用WITH子句中定义的查询名称,使查询更容易阅读。

更多详细信息here

0

它是一个CTE,也称为子查询保理。

  • SQL WITH子句只适用于Oracle 9i release 2及更高版本。
  • 形式上,WITH子句被称为子查询分解
  • 当子查询执行多次WITH子句SQL用于
  • 为递归查询(SQL-99,但不包括Oracle SQL)
同样有用

我们也可以使用SQL-99 WITH子句来代替临时表。 Oracle SQL WITH子句将计算一次聚合,给它一个名称,并允许我们在查询中稍后引用它(可能是多次)。

引用About Oracle WITH clauseOracle Subquery FactoringUsing the WITH clause to simplify complex SQL感谢Andrew

+0

Oracle支持11gR2中的[递归子查询因子分析](http://docs.oracle.com/cd/E11882_01/server.112/e10592/statements_10002.htm#BCEJGIBG)。 – 2014-10-09 15:57:24