SQL SERVER中ORACLE的连接仿真

时间:2009-06-06 14:31:48

标签: sql-server sql-server-2005

我想在SQL SERVER 2000/2005/2008中获得ORACLE的CONNECT BY PRIOR功能吗?

请帮帮我

3 个答案:

答案 0 :(得分:63)

实现递归查询的SQL标准方法,例如实现的IBM DB2和SQL ServerWITH子句。有关将CONNECT BY转换为WITH(技术上是递归CTE )的示例,请参阅this article - 该示例适用于DB2,但我相信它可行在SQL Server上也是如此。

编辑:显然原始的querant需要一个特定的例子,这里是我已经提供过URL的IBM站点的例子。给出一张表:

CREATE TABLE emp(empid  INTEGER NOT NULL PRIMARY KEY,
                 name   VARCHAR(10),
                 salary DECIMAL(9, 2),
                 mgrid  INTEGER);

其中mgrid引用员工的经理empid,任务是,获取直接或间接向Joan报告的所有人的姓名。在Oracle中,这是一个简单的CONNECT

SELECT name 
  FROM emp
  START WITH name = 'Joan'
  CONNECT BY PRIOR empid = mgrid

在SQL Server,IBM DB2或PostgreSQL 8.4(以及SQL标准中,为了它的价值;-),完全等效的解决方案是一个递归查询(更复杂的语法,但实际上,甚至更多)力量和灵活性):

WITH n(empid, name) AS 
   (SELECT empid, name 
    FROM emp
    WHERE name = 'Joan'
        UNION ALL
    SELECT nplus1.empid, nplus1.name 
    FROM emp as nplus1, n
    WHERE n.empid = nplus1.mgrid)
SELECT name FROM n

Oracle的START WITH子句成为第一个嵌套SELECT,这是递归的基本情况,用递归部分UNION编写,这只是另一个SELECT。< / p>

SQL WITH的特定风格当然记录在MSDN上,这也为使用此关键字提供了指导和限制,以及几个示例。

答案 1 :(得分:10)

@Alex Martelli的答案很棒! 但它只适用于一个元素(WHERE name = 'Joan') 如果您取出WHERE子句,查询将返回所有根行...

我根据我的情况改变了一点,所以它可以显示整个树的表格。

表格定义:

CREATE TABLE [dbo].[mar_categories] ( 
    [category]  int IDENTITY(1,1) NOT NULL,
    [name]      varchar(50) NOT NULL,
    [level]     int NOT NULL,
    [action]    int NOT NULL,
    [parent]    int NULL,
    CONSTRAINT [XPK_mar_categories] PRIMARY KEY([category])
)

level字面意思是类别0的级别:root,1:root之后的第一级,...)

和查询:

WITH n(category, name, level, parent, concatenador) AS 
(
    SELECT category, name, level, parent, '('+CONVERT(VARCHAR (MAX), category)+' - '+CONVERT(VARCHAR (MAX), level)+')' as concatenador
    FROM mar_categories
    WHERE parent is null
        UNION ALL
    SELECT m.category, m.name, m.level, m.parent, n.concatenador+' * ('+CONVERT (VARCHAR (MAX), case when ISNULL(m.parent, 0) = 0 then 0 else m.category END)+' - '+CONVERT(VARCHAR (MAX), m.level)+')' as concatenador
    FROM mar_categories as m, n
    WHERE n.category = m.parent
)
SELECT distinct * FROM n ORDER BY concatenador asc

(你不需要连接level字段,我只是为了让它更具可读性)

此查询的答案应该是:

sql return

我希望它有所帮助!

现在,我想知道如何在MySQL上做这个... ^^

答案 2 :(得分:1)

我之前没有使用过connect,但是快速搜索显示它用于树结构。在SQL Server中,您使用公用表表达式来获得类似的功能。