2017-02-21 103 views
1

您好,我在Oracle数据库中拥有这部分视图,并且必须在Microsoft Sql Server上对其进行更改。更改选择连接通过事先从Oracle到SQL Server

with V_LOCHIERARHY_N 
(nr, nivel, location, parent, systemid, siteid, orgid, count_a, count_wo, children) 
AS 
SELECT  LEVEL, LPAD (' ', 2 * (LEVEL - 1)) || l.LOCATION nivel, 
       LOCATION, PARENT, systemid, siteid, orgid, 
      (SELECT COUNT (a.ancestor) 
      FROM locancestor a 
      WHERE a.LOCATION = l.LOCATION AND a.siteid = l.siteid), 
        NVL (COUNT (w.wonum), 0) 
      FROM maximo.workorder w 

      WHERE ( w.reportdate > 
          TO_TIMESTAMP ('2006-06-19 00:00:01', 
             'YYYY-MM-DD HH24:MI:SS.FF' 
             ) 
        AND w.istask = 0 
        AND w.worktype <> 'P' 
        AND w.LOCATION = l.LOCATION 
       ) 
       AND w.status <> 'CAN'), 
      l.children 
    FROM lochierarchy l 
    START WITH l.LOCATION = 'StartPoint' 
    CONNECT BY PRIOR l.LOCATION = l.PARENT AND l.siteid = 'SiteTest' 

我需要从这个脚本中返回一个给定条目的所有子节点(可以在位置表中找到的子节点的描述)。

我有下一列的表:

Location Parent  Systemid Children Siteid Origid Lochierarchyid 
A001  StartPoint Primary 2  SiteTest X  106372 
A002  A001  Primary 2  SiteTest X  105472 
A003  A002  Primary 0  SiteTest X  98654 
A004  A002  Primary 1  SiteTest X  875543 
A004B A004  Primary 0  SiteTest X  443216 
B005  StartPoint Primary 0  SiteTest X  544321 

例如,对于给定的条目A001将返回


A002  
A003  
A004 
    A004B  
B005 

我做下面这个观点,但我不知道如何将其与第一个整合。此外,它不会返回我的列表中corectly为了

Parent 
Children 1 of parent 
    Children a of children 1 
    children b of children 1 
children 2 of parent 
    children a1 of children 2 and so on. 

WITH testCTE AS 
(
    SELECT l.parent, l.location as child, l.location, l.lochierarchyid 
    FROM lochierarchy l 
    where location='SecondLocation' --and siteid='SiteTest' 
     UNION ALL 
    SELECT c.Parent, l.parent, l.location, l.lochierarchyid 
    FROM lochierarchy l 
    INNER JOIN testCTE c ON l.parent = c.location 
) 
    SELECT * 
    FROM testCTE c 
    order BY c.parent,child asc 
; 

可以请人帮助我吗? :)

+0

如果我有一段时间,我会努力寻找解决方案。你也可以自己解决,并提供一些帮助。下面的文章逐步展示了如何通过递归子查询分解重现“connect by”查询的所有功能:https://oracle-base.com/articles/11g/recursive-subquery-factoring-11gr2 – mathguy

+0

请做*不*破坏你的帖子。 –

+0

[如何从SQL Server中的SELECT进行更新?](http://stackoverflow.com/questions/2334712/how-to-update-from-a-select-in-sql-server) – Madalina

回答

0

下面是如何使用递归查询来做到这一点(在Oracle中,我知道的唯一的味道)。 “网络”报道SQL Server也实现了递归查询,并且使用相同的语法(我相信所有这些都符合SQL标准,所以这并不奇怪)。试一试。

我没有创建表格,而是将所有测试数据放在第一个CTE中。当您尝试此解决方案时,首先删除名为inputs的CTE,然后在查询的其余部分使用您的实际表名。

with 
    inputs (location, parent) as (
     select 'A001' , 'Downstream' from dual union all 
     select 'A002' , 'A001'  from dual union all 
     select 'A003' , 'A002'  from dual union all 
     select 'A004' , 'A002'  from dual union all 
     select 'A004B', 'A004'  from dual union all 
     select 'B005' , 'Downstream' from dual 
    ), 
    r (lvl, location) as (
     select 1, location 
     from inputs 
     where parent = 'Downstream' 
     union all 
     select r.lvl + 1, i.location 
     from r join inputs i on r.location = i.parent 
    ) 
    search depth first by lvl set ord 
select lpad(' ', 2 * (lvl-1), ' ') || location as location 
from r 
order by ord 
; 


LOCATION 
-------------------- 
A001 
    A002 
    A003 
    A004 
     A004B 
B005 

6 rows selected. 

ADDED:看来SQL Server不具备递归CTE的(或者语法是不同的)的search depth/breadth first条款。在任何情况下,这里是一个原始的 “手册” 执行相同的:

with ( ......... ), 
    r (lvl, location, ord) as (
     select 1, location, location 
     from inputs 
     where parent = 'Downstream' 
     union all 
     select r.lvl + 1, i.location, r.location || '/' || i.location 
     from r join inputs i on r.location = i.parent 
    ) 
select lpad(' ', 2 * (lvl-1), ' ') || location as location 
from r 
order by ord 
; 
+0

@AndreeaEnache - 也许SQL Server没有用于递归查询的SEARCH子句(或者语法可能不同)。我没有SQL Server,但是:请在最后注释掉该行和ORDER BY子句后再试一次。其余的工作?如果是这样,您可以研究相当于SQL Server的SEARCH DEPTH FIRST;我会考虑一下,看看我的查询中'ord'的正确公式是什么(我相信,Oracle使用相同的公式来使订单正确)。 – mathguy

+0

@AndreeaEnache - 好的,我添加到我的答案中:我从零开始实施了一个基本的“搜索深度”。 – mathguy

+0

:-)这就是为什么你需要知道Oracle和SQL Server的人的帮助......是的,'||'是Oracle中的连接,不知道SQL Server使用什么。对于你得到的错误:我认为这是'ord'的事情,我进一步假设你的LOCATION实际上并不是一个字符串。对?如果它是NUMBER,那会导致一个问题,因为我把它当作一个字符串来处理,没有任何转换。如果它是一个NUMBER,那么ord在锚中是NUMBER,但它在递归分支中连接后变成一个字符串。如果您的位置确实是某个(某些SQL Server类型的)编号,请将其包装在TO_CHAR()或等价物中。 – mathguy

0

继mathguy提出的查询,修改MSSQL(2012)

with 
     inputs (location, parent) as (
      select 'A001' , 'StartPoint' union all 
      select 'A002' , 'A001'  union all 
      select 'A003' , 'A002'  union all 
      select 'A004' , 'A002'  union all 
     select 'A004B', 'A004'  union all 
     select 'B005' , 'StartPoint' 
    ), 
    r (lvl, location, ord) as (
     select 1, location, CAST(location AS VARCHAR(400)) 
     from inputs 
     where parent = 'StartPoint' 
     union all 
     select r.lvl + 1, i.location, CAST(r.location + '/' + i.location AS VARCHAR(400)) 
     from r join inputs i on r.location = i.parent 
    ) 
select REPLICATE(' ', 2 * (lvl-1)) + location as location 
from r 
order by ord 
; 

输出继电器:

location 
------------------------------------------------------------------- 
A001 
    A002 
    A003 
    A004 
     A004B 
B005