我想在SQL SERVER 2000/2005/2008中获得ORACLE的CONNECT BY PRIOR功能吗?
请帮帮我
答案 0 :(得分:63)
实现递归查询的SQL标准方法,例如实现的IBM DB2和SQL Server是WITH
子句。有关将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
字段,我只是为了让它更具可读性)
此查询的答案应该是:
我希望它有所帮助!
现在,我想知道如何在MySQL上做这个... ^^
答案 2 :(得分:1)
我之前没有使用过connect,但是快速搜索显示它用于树结构。在SQL Server中,您使用公用表表达式来获得类似的功能。