2017-02-21 102 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