2016-04-15 1 views
0

J'ai un jeu de données avec deux colonnes: index et niveau.Requête SQL - Obtenir l'index parent à partir du niveau et de l'index enfant

Le niveau est un nombre indiquant le niveau dans la hiérarchie des enregistrements enfants parents imbriqués.

Les enregistrements sont dans l'ordre hiérarchique et l'index est simplement le numéro de ligne de l'enregistrement.

La règle est que le niveau a niveau = l'enfant dossier parent de tout enregistrement - 1.

Mon défi est d'identifier l'index du parent en fonction de cette règle.

Pour chaque enregistrement, j'ai besoin d'une requête SQL qui obtiendra l'index parent de l'enregistrement.

La requête SQL sera une jointure réflexive et obtenir la valeur de l'indice max où l'auto join index < child.index et l'auto se joindre niveau = child.level

Je besoin d'aide pour comprendre comment écrire ce SQL.

Je peux utiliser MS Access ou utiliser SQL dans VBA pour effectuer cette requête.

Ceci est une représentation visuelle de l'ensemble de données.

enter image description here

Ce sont des données échantillon et résultat attendu .. veulent obtenir l'indice parent .. niveau parent est le niveau de l'enfant - 1.

Index,Level Number,Parent Level,Parent Index 
1,1,1,1 
2,2,1,1 
4,4,3,3 
9,9,8,8 
3,3,2,2 
5,5,4,4 
8,8,7,7 
6,6,5,5 
7,7,6,6 
10,10,9,9 
11,11,10,10 
12,12,11,11 
13,13,12,12 
14,14,13,13 
15,14,13,13 
16,14,13,13 
17,14,13,13 
18,14,13,13 
19,14,13,13 
20,14,13,13 
21,13,12,12 
22,13,12,12 
23,13,12,12 
24,14,13,23 
25,14,13,23 
26,14,13,23 
27,11,10,10 
28,9,8,8 
29,9,8,8 
30,9,8,8 
31,9,8,8 
32,9,8,8 
33,9,8,8 
34,9,8,8 
35,8,7,7 
36,9,8,35 
37,10,9,36 
38,11,10,37 
39,11,10,37 
40,12,11,39 
41,12,11,39 
42,13,12,41 
43,13,12,41 
44,13,12,41 
45,11,10,37 
46,12,11,45 
47,13,12,46 
48,14,13,47 
49,14,13,47 
50,14,13,47 
51,14,13,47 
52,14,13,47 
53,14,13,47 
54,14,13,47 
55,13,12,46 
56,13,12,46 
57,13,12,46 
58,9,8,35 
59,9,8,35 
60,9,8,35 
61,9,8,35 
62,8,7,7 
63,8,7,7 
64,8,7,7 
65,8,7,7 
66,8,7,7 
67,8,7,7 
68,8,7,7 

Edité pour ajouter: J'ai essayé de le faire dans Excel Power Query, et trouvé une réponse, mais cela prend une éternité à courir si besoin de trouver une solution SQL VBA/ADO. Mais voici Power Query solution pour aider à donner des idées sur la façon de le faire SQL.

let 
    Source = Excel.CurrentWorkbook(){[Name="Tabelle3"]}[Content], 
    ParentIndex = Table.AddColumn(Source, "ParentIndex", each let Index=[Index], LN=[Level Number] in List.Max(Table.SelectRows(Source, each _[Index] < Index and _[Level Number]=LN-1)[Index])), 
    #"Merged Queries" = Table.NestedJoin(ParentIndex,{"ParentIndex"},ParentIndex,{"Index"},"NewColumn",JoinKind.LeftOuter), 
    #"Expanded NewColumn" = Table.ExpandTableColumn(#"Merged Queries", "NewColumn", {"Level Number"}, {"Level Number.1"}) 
in 
    #"Expanded NewColumn" 

Cette solution d'alimentation requête trouve indice maximum dans lequel chaque index de ligne < tout d'index et level = Niveau -1

+0

un certain échantillon avec résultat escompté aiderait – TheGameiswar

+0

S'il vous plaît fournir des exemples de données et le résultat attendu. –

+0

s'il vous plaît ne pas inclure des données en tant qu'image. Nous devrions le re-taper ... S'il vous plaît ajouter à vos données un texte copié et réutilisable. Best serait un scénario de test avec une instruction CREATE TABLE et quelques instructions INSERT INTO. Vous obtiendriez beaucoup plus de bonnes réponses ... – Shnugo

Répondre

1
DECLARE @t TABLE (val INT) 
INSERT INTO @t 
VALUES 
    (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13), 
    (14),(14),(14),(14),(14),(14),(14),(13),(13),(13),(14),(14),(14),(11) 

SELECT REPLICATE(' ', val) + CAST(val AS VARCHAR(10)) 
FROM @t 

sortie

----------------------------- 
1 
    2 
    3 
    4 
    5 
     6 
     7 
     8 
     9 
      10 
      11 
      12 
      13 
       14 
       14 
       14 
       14 
       14 
       14 
       14 
      13 
      13 
1
--http://stackoverflow.com/questions/36639349/sql-query-get-parent-index-from-level-and-child-index 
declare @table table 
(idx int, level int) 

insert into @table 
(idx,level) 
values 
(1,1), 
(2,2), 
(3,3), 
(4,4), 
(5,5), 
(6,6), 
(7,7), 
(8,8), 
(9,9), 
(10,10), 
(11,11), 
(12,12), 
(13,13), 
(14,14), 
(15,14), 
(16,14), 
(17,14), 
(18,14), 
(19,14), 
(20,14), 
(21,14), 
(22,13), 
(23,13), 
(24,13), 
(25,14), 
(26,14), 
(27,14), 
(28,11), 
(29,9), 
(30,8) 

select v.idx,v.level,v.parentlevel,u.idx parentidx 
from 
(
select s.* from        --Find the first idx,level 
(
select t.*, t.level - 1 as parentlevel, 
     row_number() over (partition by level order by idx,level) rownum 
from @table t 
) s 
where rownum = 1 
) u 
join          --join to every occurance of 
(select t2.*, t2.level - 1 parentlevel, 
     1 as rownum 
from @table t2 
) v 
on (v.parentlevel = u.level and v.rownum = u.rownum) 
union          --and put 1 back 
select w.idx,w.level,w.level,w.idx 
from @table w 
where w.idx = 1 
order by v.idx 
+0

J'ai demandé TSQL alors j'ai eu ce que j'ai demandé. Cela fonctionne très bien sur SQL Server, mais les fonctions de fenêtrage TSQL découvertes, par exemple sur la partition, ne sont pas disponibles avec Jet/ACE SQL dans une nouvelle question [ici] (http://stackoverflow.com/questions/36674269/excel-vba-ado- sql-syntax-error-in-from-clause) Voulez-vous modifier SQL pour Jet/ACE SQL? – curtisp

+0

Juste enlevé vérifier la réponse. A regardé de plus près. Cela n'a pas eu le résultat souhaité. Ces résultats SQL étaient corrects jusqu'à Index 24. Index 24 index parent aurait dû être 23 pas 13. Le groupement recherche trop loin dans la hiérarchie pour la valeur min. – curtisp

+0

Les données d'échantillon pour l'index 24 est 24,13 devrait-il être 24,24? –