2017-02-21 3 views
1

Bonjour, j'ai cette partie d'une vue dans une base de données Oracle et je dois le modifier sur Microsoft SQL Server.Modifier sélectionner avec se connecter par avant d'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' 

Ce que je besoin de ce script est de retourner tous les enfants d'une entrée donnée (la description des enfants qui se trouvent dans le tableau des emplacements).

J'ai une table avec des colonnes suivantes:

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 

Par exemple, pour A001 d'entrée retourneront dans


A002  
A003  
A004 
    A004B  
B005 

J'ai fait ce point de vue ci-dessous, mais je ne sais pas comment pour l'intégrer avec le premier. En outre, il ne me renvoie pas la liste dans l'ordre 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 
; 

peut plaire à quelqu'un me aider? :)

+0

Si j'ai un peu de temps, je vais travailler sur une solution. Vous pouvez également être en mesure de le comprendre par vous-même, avec un peu d'aide. L'article ci-dessous montre, étape par étape, comment reproduire toutes les fonctionnalités d'une requête "connect by" avec l'affacturage sous-requête récursive: https://oracle-base.com/articles/11g/recursive-subquery-factoring-11gr2 – mathguy

+0

Please ne * vandalise * pas * vos messages. –

+0

Copie possible de [Comment mettre à jour à partir d'un SELECT dans SQL Server?] (Http://stackoverflow.com/questions/2334712/how-to-update-from-a-select-in-sql-server) – Madalina

Répondre

0

Voici comment vous pouvez faire cela (dans Oracle, la seule saveur que je connais) en utilisant une requête récursive. "Le web" rapporte que SQL Server implémente aussi des requêtes récursives, et avec la même syntaxe (je crois que tout ceci est compatible avec SQL Standard, donc ce n'est pas surprenant). Essaie. Au lieu de créer une table, j'ai placé toutes les données de test dans le premier CTE. Lorsque vous essayez cette solution, supprimez d'abord le fichier CTE nommé inputs et utilisez le nom de votre table dans le reste de la requête.

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. 

AJOUTÉE: Il semble SQL Server ne pas la search depth/breadth first clause de CTE récursive (ou peut-être la syntaxe est différente). Dans tous les cas, voici une mise en œuvre "manuel" primitif du même:

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 - Peut-être que SQL Server n'a pas la clause SEARCH pour les requêtes récursives (ou peut-être que la syntaxe est différente). Je n'ai pas SQL Server, mais: veuillez réessayer après avoir commenter cette ligne et la clause ORDER BY à la fin. Est-ce que le reste fonctionne? Si c'est le cas, vous pouvez rechercher l'équivalent de SEARCH DEPTH FIRST pour SQL Server; Je vais réfléchir un peu pour voir quelle est la bonne formule pour le 'ord 'dans ma requête (la même formule, j'en suis sûr, qu'Oracle utilise pour obtenir la bonne commande). – mathguy

+0

@AndreeaEnache - OK, j'ai ajouté à ma réponse: J'ai mis en place une "recherche approfondie" rudimentaire d'abord à partir de zéro. – mathguy

+0

:-) C'est pourquoi vous avez besoin de l'aide de quelqu'un qui connaît à la fois Oracle et SQL Server ... oui, '||' est une concaténation dans Oracle, pas sûr de ce que SQL Server utilise. Pour l'erreur que vous obtenez: Je suppose que c'est pour la chose 'ord ', et je suppose en outre que votre LOCATION n'est pas réellement une chaîne. Droite? Si c'est un nombre, cela causerait un problème parce que je le traite comme une chaîne, sans conversions. Si c'est un NUMBER alors ord est un NUMBER dans l'ancre mais il devient une chaîne après concaténation dans la branche récursive. Si votre emplacement est en fait un nombre (de type SQL Server), placez-le dans TO_CHAR() ou équivalent. – mathguy

0

Suite à la requête proposée par mathguy, modifié pour 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 
; 

Ouput:

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