2010-07-30 16 views
4

Nous avons une structure de structure organisationnelle générale. Pensez à une hiérarchie arborescente ou pyramidale. Nous avons essentiellement plusieurs "arbres" que nous voulons montrer. Sur pour une entreprise, un pour un autre ETC.Requête SQL Server ou outil permettant d'afficher des données hiérarchiques

Est-ce que quelqu'un connaît un bon moyen d'afficher ces données? SQL Query serait bien, doutez que ce soit possible, mais je ne serais pas contre l'utilisation d'un outil OTS (de préférence gratuit). Je voudrais également éviter un certain type de rapport. Je n'ai pas besoin d'une solution réelle juste besoin de savoir si c'est possible. Donc si vous dites SQL si vous pouvez me donner un exemple de 2 table de montrer une racine un congé je serais heureux.

La structure est assez générale

alt text

Et chaque table est reliée par une clé de substitution CompanyID, CompanyGroupID, etc.

Toutes les suggestions sur les moyens que nous pourrions afficher/requête pour ces données? dernier recours est d'écrire un rapide C# application Windows ...

Nous aimerions le voir sous forme d'arbre:

--      1-Company 
--     /  \ 
--    CompanyGroupA CompanyGroupB 
--   /  \    \ 
-- CompanyStoreA1 CompanyStoreA1 CompanyStoreB 
-- / \   / \ 
--Employee A   B  C 

Pour tenter de plaire aux masses est ici un script de test par exemple pour remplir la requête .

DECLARE @Company table (id int, name varchar(40)) 
INSERT @Company VALUES (1,'Living Things') 
INSERT @Company VALUES (2,'Boring Company') 


DECLARE @CompanyGroup table (id int, name varchar(40), CompanyID int) 
INSERT @CompanyGroup VALUES (1,'Pets',1) 
INSERT @CompanyGroup VALUES (2,'Humans',1) 
INSERT @CompanyGroup VALUES (3,'Electronics',2) 
INSERT @CompanyGroup VALUES (4,'Food',2) 


DECLARE @CompanyStore table (id int, name varchar(40), CompanyGroupID int) 
INSERT @CompanyStore VALUES (1,'PetsStoreA',1) 
INSERT @CompanyStore VALUES (2,'PetsStoreB',1) 
INSERT @CompanyStore VALUES (3,'PetsStoreC',1) 
INSERT @CompanyStore VALUES (4,'PetsStoreD', 1) 
INSERT @CompanyStore VALUES (5,'HumansStore',2) 
INSERT @CompanyStore VALUES (6,'FoodStore',3) 

La solution finale a été assez impressionnant j'ai modifié le usp_DrawTree d'accepter varchar vs ints parce que je devais faire ma requête ids unique. J'ai ensuite fait un select/union tout et construit la relation parent-enfant.

select * into #TreeData from (
    select ID='C' + cast(id as varchar(10)), 
     ParentID=null, 
     DataForBox=name + '(' + cast(id as varchar(10)) + ')', 
     ExtraInfo='', 
     SortColumn=name 
    from Company c 
) 
union all (
    select ID='CG' + cast(id as varchar(10)), 
     ParentID=cg.CompanyID , 
     DataForBox=name + '(' + cast(id as varchar(10)) + ')', 
     ExtraInfo='', 
     SortColumn=name 
    from CompanyGroup cg join Company c on c.ID=cg.CompanyID 
) 
//union all rest of hierarchy 
) 
+0

Je pensais que ce serait peut-être facile à interroger juste pour chaque CompanyGroup pour une carte d'identité, l'exportation au format CSV, puis interroger pour tous les CompanyStores de l'exportation Groupes de l'entreprise au format CSV, puis les mettre dans des onglets dans Excel et créer un rapport ... mais même cela pourrait être désordonné. – Nix

+0

Mon dernier montage a-t-il répondu à votre question? –

+0

Je veux dire son plat. Je cherche un arbre visuel comme vous dépeignez dans vos commentaires pour les insertions. Il est difficile d'imaginer les niveaux inférieurs de l'arbre lorsque vous les regardez dans GridView. Nous allons regarder cet arbre et nous devons voir les différentes branches côte à côte. Je pense que cela va juste devoir être une application personnalisée ou un rapport. – Nix

Répondre

0

Vous pouvez utiliser les services de génération de rapports pour l'afficher avec SQL 2008; Si vous êtes chanceux, il pourrait déjà être configuré - si ce n'est pas facile à faire. Vous pouvez utiliser l'exploration dans les fonctionnalités des services de création de rapports pour permettre à vos utilisateurs d'accéder aux données et de les extraire très facilement.

En termes de requête; l'arbre pousse-t-il ou est-il fixé? La requête SQL pour extraire les données de la base de données est assez simple.

Select 
    CompanyName, 
    CompanyGroupName, 
    CompanyStoreName, 
    CompanyEmployeeForename, 
    CompanyEmployeeSurname 

From tblCompanies com 
left outer join tblCompanyGroups cg 
on com.CompanyGroupID = cg.CompanyGroupID 

Left outer Join tblCompanyStore cs 
on com.CompanyID = cs.CompanyID 

left outer join tblCompanyEmployees ce 
on com.CompanyID = ce.CompanyName 
+0

L'arbre est fixé jusqu'au niveau inférieur. Mais pour la plupart, le niveau inférieur (employés) ne sera probablement jamais affiché en entier. – Nix

1

vous ne fournissez aucune structure de la table, alors voici un exemple d'un traitement CTE récursive une structure arborescente:

--go through a nested table supervisor - user table and display the chain 
DECLARE @Contacts table (id varchar(6), first_name varchar(10), reports_to_id varchar(6)) 
INSERT @Contacts VALUES ('1','Jerome', NULL) -- tree is as follows: 
INSERT @Contacts VALUES ('2','Joe' ,'1')  --      1-Jerome 
INSERT @Contacts VALUES ('3','Paul' ,'2')  --     /  \ 
INSERT @Contacts VALUES ('4','Jack' ,'3')  --    2-Joe   9-Bill 
INSERT @Contacts VALUES ('5','Daniel','3')  --   /  \    \ 
INSERT @Contacts VALUES ('6','David' ,'2')  --  3-Paul   6-David  10-Sam 
INSERT @Contacts VALUES ('7','Ian' ,'6')  -- / \   / \ 
INSERT @Contacts VALUES ('8','Helen' ,'6')  -- 4-Jack 5-Daniel 7-Ian 8-Helen 
INSERT @Contacts VALUES ('9','Bill ' ,'1')  -- 
INSERT @Contacts VALUES ('10','Sam' ,'9')  -- 

DECLARE @Root_id char(4) 

--get complete tree--------------------------------------------------- 
SET @Root_id=null 
PRINT '@Root_id='+COALESCE(''''[email protected]_id+'''','null') 
;WITH StaffTree AS 
(
    SELECT 
     c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf 
     FROM @Contacts     c 
      LEFT OUTER JOIN @Contacts cc ON c.reports_to_id=cc.id 
     WHERE [email protected]_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL) 
    UNION ALL 
     SELECT 
      s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1 
     FROM StaffTree   t 
      INNER JOIN @Contacts s ON t.id=s.reports_to_id 
    WHERE [email protected]_id OR @Root_id IS NULL OR t.LevelOf>1 
) 
SELECT * FROM StaffTree 


--get all below 2--------------------------------------------------- 
SET @Root_id=2 
PRINT '@Root_id='+COALESCE(''''[email protected]_id+'''','null') 
;WITH StaffTree AS 
(
    SELECT 
     c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf 
     FROM @Contacts     c 
      LEFT OUTER JOIN @Contacts cc ON c.reports_to_id=cc.id 
     WHERE [email protected]_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL) 
    UNION ALL 
     SELECT 
      s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1 
     FROM StaffTree   t 
      INNER JOIN @Contacts s ON t.id=s.reports_to_id 
    WHERE [email protected]_id OR @Root_id IS NULL OR t.LevelOf>1 
) 
SELECT * FROM StaffTree 

--get all below 6--------------------------------------------------- 
SET @Root_id=6 
PRINT '@Root_id='+COALESCE(''''[email protected]_id+'''','null') 
;WITH StaffTree AS 
(
    SELECT 
     c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf 
     FROM @Contacts     c 
      LEFT OUTER JOIN @Contacts cc ON c.reports_to_id=cc.id 
     WHERE [email protected]_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL) 
    UNION ALL 
     SELECT 
      s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1 
     FROM StaffTree   t 
      INNER JOIN @Contacts s ON t.id=s.reports_to_id 
    WHERE [email protected]_id OR @Root_id IS NULL OR t.LevelOf>1 
) 
SELECT * FROM StaffTree 

SORTIE:

@Root_id=null 
id  first_name reports_to_id Manager_id Manager_first_name LevelOf 
------ ---------- ------------- ---------- ------------------ ----------- 
1  Jerome  NULL   NULL  NULL    1 
2  Joe  1    1   Jerome    2 
9  Bill  1    1   Jerome    2 
10  Sam  9    9   Bill    3 
3  Paul  2    2   Joe    3 
6  David  2    2   Joe    3 
7  Ian  6    6   David    4 
8  Helen  6    6   David    4 
4  Jack  3    3   Paul    4 
5  Daniel  3    3   Paul    4 

(10 row(s) affected) 

@Root_id='2 ' 
id  first_name reports_to_id Manager_id Manager_first_name LevelOf 
------ ---------- ------------- ---------- ------------------ ----------- 
2  Joe  1    1   Jerome    1 
3  Paul  2    2   Joe    2 
6  David  2    2   Joe    2 
7  Ian  6    6   David    3 
8  Helen  6    6   David    3 
4  Jack  3    3   Paul    3 
5  Daniel  3    3   Paul    3 

(7 row(s) affected) 

@Root_id='6 ' 
id  first_name reports_to_id Manager_id Manager_first_name LevelOf 
------ ---------- ------------- ---------- ------------------ ----------- 
6  David  2    2   Joe    1 
7  Ian  6    6   David    2 
8  Helen  6    6   David    2 

(3 row(s) affected) 

EDIT basé sur les tables données et les données de l'OP:

essayer quelque chose li ke ceci:

SET NOCOUNT ON 
DECLARE @Company table (id int, name varchar(40)) 
INSERT @Company VALUES (1,'Living Things') 
INSERT @Company VALUES (2,'Boring Company') 

DECLARE @CompanyGroup table (id int, name varchar(40), CompanyID int) 
INSERT @CompanyGroup VALUES (1,'Pets'  ,1) 
INSERT @CompanyGroup VALUES (2,'Humans'  ,1) 
INSERT @CompanyGroup VALUES (3,'Electronics' ,2) 
INSERT @CompanyGroup VALUES (4,'Food'  ,2) 

DECLARE @CompanyStore table (id int, name varchar(40), CompanyGroupID int) 
INSERT @CompanyStore VALUES (1,'PetsStoreA' ,1) 
INSERT @CompanyStore VALUES (2,'PetsStoreB' ,1) 
INSERT @CompanyStore VALUES (3,'PetsStoreC' ,1) 
INSERT @CompanyStore VALUES (4,'PetsStoreD' ,1) 
INSERT @CompanyStore VALUES (5,'HumansStore' ,2) 
INSERT @CompanyStore VALUES (6,'FoodStore' ,3) 

--not provided by the OP, so I made it up 
DECLARE @CompanyEmployees table (id int, name varchar(10), reports_to_id int, CompanyStoreID int) 
INSERT @CompanyEmployees VALUES (1,'Jerome', NULL ,1) -- tree is as follows: 
INSERT @CompanyEmployees VALUES (2,'Joe' ,1  ,1)  --      PetsStoreA    PetsStoreB   PetStoreC   FoodStore 
INSERT @CompanyEmployees VALUES (3,'Paul' ,2  ,1)  --      1-Jerome     11-Alan   14-Ben    18-apple 
INSERT @CompanyEmployees VALUES (4,'Jack' ,3  ,1)  --     /  \    / \   /    / \ 
INSERT @CompanyEmployees VALUES (5,'Daniel',3  ,1)  --    2-Joe   9-Bill   12-Ally 13-Abby 15-Bill   19-pear 20-grape 
INSERT @CompanyEmployees VALUES (6,'David' ,2  ,1)  --   /  \    \       / \     /
INSERT @CompanyEmployees VALUES (7,'Ian' ,6  ,1)  --  3-Paul   6-David  10-Sam      16-Bjorn 17-Benny   21-rasin 
INSERT @CompanyEmployees VALUES (8,'Helen' ,6  ,1)  -- / \   / \ 
INSERT @CompanyEmployees VALUES (9,'Bill ' ,1  ,1)  -- 4-Jack 5-Daniel 7-Ian 8-Helen 
INSERT @CompanyEmployees VALUES (10,'Sam' ,9  ,1)  -- 
INSERT @CompanyEmployees VALUES (11,'Alan' ,NULL ,2)  --to see all trees, scroll--->> 
INSERT @CompanyEmployees VALUES (12,'Ally' ,11 ,2)  -- 
INSERT @CompanyEmployees VALUES (13,'Abby' ,11 ,2)  -- 
INSERT @CompanyEmployees VALUES (14,'Ben' ,NULL ,3)  --  
INSERT @CompanyEmployees VALUES (15,'Bill' ,14 ,3)  -- 
INSERT @CompanyEmployees VALUES (16,'Bjorn',15 ,3)  -- 
INSERT @CompanyEmployees VALUES (17,'Benny',15 ,3)  -- 
INSERT @CompanyEmployees VALUES (18,'apple',NULL ,6)  -- 
INSERT @CompanyEmployees VALUES (19,'pear' ,18 ,6)  -- 
INSERT @CompanyEmployees VALUES (20,'grape',18 ,6)  -- 
INSERT @CompanyEmployees VALUES (21,'rasin',21 ,6)  -- 
SET NOCOUNT OFF 

;WITH StaffTree AS 
(
    SELECT 
     c.id, c.name, c.reports_to_id, c.reports_to_id as Manager_id, cc.name AS Manager_name, 1 AS LevelOf, c.CompanyStoreID 
     FROM @CompanyEmployees    c 
      LEFT OUTER JOIN @CompanyEmployees cc ON c.reports_to_id=cc.id 
     WHERE c.reports_to_id IS NULL 
    UNION ALL 
     SELECT 
      s.id, s.name, s.reports_to_id, t.id, t.name, t.LevelOf+1, s.CompanyStoreID 
     FROM StaffTree     t 
      INNER JOIN @CompanyEmployees s ON t.id=s.reports_to_id 
) 
SELECT 
    c.id AS CompanyID, c.name AS CompanyName 
     ,g.id AS CompanyGroupID, g.name AS CompanyName 
     ,s.id AS CompanyStoreID, s.name AS CompanyStoreName 
     ,t.id AS EmployeeID, t.name as EmployeeName, t.Manager_id, t.Manager_name, t.LevelOf 
    FROM @Company    c 
     LEFT JOIN @CompanyGroup g ON c.id=g.CompanyID 
     LEFT JOIN @CompanyStore s ON g.id=s.CompanyGroupID 
     LEFT JOIN StaffTree  t ON s.id=t.CompanyStoreID 
    ORDER BY c.name,g.name,s.name,s.ID,t.LevelOf,t.name 

SORTIE:

CompanyID CompanyName CompanyGroupID CompanyName CompanyStoreID CompanyStoreName EmployeeID EmployeeName Manager_id Manager_name LevelOf 
--------- -------------- -------------- ----------- -------------- ---------------- ----------- ------------ ----------- ------------ ------- 
2   Boring Company 3    Electronics 6    FoodStore  18   apple  NULL  NULL   1 
2   Boring Company 3    Electronics 6    FoodStore  20   grape  18   apple  2 
2   Boring Company 3    Electronics 6    FoodStore  19   pear   18   apple  2 
2   Boring Company 4    Food  NULL   NULL    NULL  NULL   NULL  NULL   NULL 
1   Living Things 2    Humans  5    HumansStore  NULL  NULL   NULL  NULL   NULL 
1   Living Things 1    Pets  1    PetsStoreA  1   Jerome  NULL  NULL   1 
1   Living Things 1    Pets  1    PetsStoreA  9   Bill   1   Jerome  2 
1   Living Things 1    Pets  1    PetsStoreA  2   Joe   1   Jerome  2 
1   Living Things 1    Pets  1    PetsStoreA  6   David  2   Joe   3 
1   Living Things 1    Pets  1    PetsStoreA  3   Paul   2   Joe   3 
1   Living Things 1    Pets  1    PetsStoreA  10   Sam   9   Bill   3 
1   Living Things 1    Pets  1    PetsStoreA  5   Daniel  3   Paul   4 
1   Living Things 1    Pets  1    PetsStoreA  8   Helen  6   David  4 
1   Living Things 1    Pets  1    PetsStoreA  7   Ian   6   David  4 
1   Living Things 1    Pets  1    PetsStoreA  4   Jack   3   Paul   4 
1   Living Things 1    Pets  2    PetsStoreB  11   Alan   NULL  NULL   1 
1   Living Things 1    Pets  2    PetsStoreB  13   Abby   11   Alan   2 
1   Living Things 1    Pets  2    PetsStoreB  12   Ally   11   Alan   2 
1   Living Things 1    Pets  3    PetsStoreC  14   Ben   NULL  NULL   1 
1   Living Things 1    Pets  3    PetsStoreC  15   Bill   14   Ben   2 
1   Living Things 1    Pets  3    PetsStoreC  17   Benny  15   Bill   3 
1   Living Things 1    Pets  3    PetsStoreC  16   Bjorn  15   Bill   3 
1   Living Things 1    Pets  4    PetsStoreD  NULL  NULL   NULL  NULL   NULL 

(23 row(s) affected) 

EDIT après modification de l'OP indiquant que We would like to see it in tree form.

La question est étiquetée sql-server-2008 et hierarchical-data, et l'OP souhaite effectuer un formatage complexe pour l'affichage des données. Cependant, ce type de traitement et d'affichage n'est pas le domaine de TSQL et est un exemple très clair d'où le langage d'application devrait traiter et formater les données à plat fournies par une requête SQL. J'ai fourni une telle requête qui pourrait être utilisée par une application pour construire un affichage d'arbre visuel. Notez également que l'exemple de l'arbre simple (pas plus de deux enfants par parent) peut ne pas être très réaliste et lorsque de nombreux enfants existent pour un parent seul, l'affichage devient difficile à construire et ne plaît pas à l'œil.

+0

Est-ce juste une table récursive (fks à elle-même?). Ça va me prendre un peu de temps, mais je passerai au crible ça ... je ne t'ai pas donné d'infos parce que je voulais le garder à un niveau élevé. Ils sont tous rejoints par des clés de substitution, j'ai pensé que ce serait tout ce dont vous aviez besoin. Merci et je reviendrai vers vous. – Nix

+0

Cela ne me sert à rien ... vous utilisez la même table? J'ai 3 tables associatives que je rejoins ... – Nix

+0

@Nix, j'ai dit 'vous ne fournissez aucune structure de table, donc voici un échantillon d'un CTE récursif traitant une structure arborescente', mot-clé' sample'. Si vous vous attendez à couper et coller dans une réponse, vous devez fournir ** plus de détails ** dans votre question. Si vous avez vraiment besoin d'une réponse à cette question, vous devez fournir les instructions DECLARE et INSERT équivalentes pour vos tables, comme je l'ai dans mon code ci-dessus, ainsi que l'ensemble de résultats que vous souhaitez obtenir à partir de ces exemples de données. Bref, aucune réponse ne peut être ce que vous voulez, il est impossible de deviner la structure de votre table et de lire ce que vous voulez. –