2010-07-30 37 views
4

我们有一个通用的组织表结构,将其视为树或金字塔层次结构。我们基本上有多个我们想展示的“树”。在一家公司上,另一家为另一家公司。用于显示分层数据的SQL Server查询或工具

有谁知道显示这些数据的好方法吗? SQL查询会很好,怀疑它是可能的,但我不会反对使用一些OTS工具(最好是免费的)。我也想避免某种类型的报告。我不需要一个实际的解决方案,只需要知道,如果它可能的。所以,如果你说SQL,如果你可以给我一个2表的示例,显示一个根,我会很高兴。

结构是相当普遍的

alt text

每个表通过代理键CompanyID,CompanyGroupID链接等

的方式,我们可以显示/查询这个数据有什么建议?最后一招是编写一个简单的C#Windows应用程序...

我们希望看到它在树的形式:

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

在尝试这里请群众就是一个例子测试脚本来填充查询。

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) 

最终的解决方案是相当真棒我修改了usp_DrawTree接受VARCHAR VS整数,因为我已经让我的查询的ID是唯一的。然后,我做了一个select/union all并构建了父子关系。

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

我想这可能是容易的,只是查询每一个CompanyGroup一个ID,导出为CSV,然后查询本公司组导出为CSV的所有CompanyStores,然后把它们在Excel选项卡并创建一个报告......但即使这可能是混乱。 – Nix 2010-07-30 13:09:55

+0

我的最新编辑是否回答你的问题? – 2010-08-10 12:27:00

+0

我的意思是它的单位。我正在寻找一个可视化树,就像你在插入评论中描绘的一样。当你在GridView中查看它们时,很难设想树中的较低层次。我们将会看着这棵树,并且需要看到不同的树枝并排。我想这只是一个自定义的应用程序或报告。 – Nix 2010-08-11 12:22:17

回答

0

您可以使用报告服务将其显示回来,其中包含SQL 2008;如果你幸运的话,它可能已经设置好了 - 如果不是那么容易的话。您可以在报告服务的功能中使用钻取功能,以便您的用户非常容易地根据需要钻入和钻出数据。

就查询而言;树是否增长或者是否固定?从数据库中获取数据的SQL查询非常简单。

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

树被固定到底层。但大部分底层(员工)可能永远不会全部显示。 – Nix 2010-07-30 13:28:53

1

你不提供任何表结构,所以这里是一个递归CTE处理树形结构的样本:

--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 

OUTPUT:

@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) 

编辑基于对OP的给定表格和数据:

试一下li柯本:

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 

OUTPUT:

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) 

编辑 OP的编辑指出,We would like to see it in tree form后。

这个问题被标记为sql-server-2008hierarchical-data,OP想要做复杂的格式来显示数据。然而,这种类型的处理和显示不是TSQL的领域,并且是应用程序语言应该处理和格式化由SQL查询提供的平面数据的非常明显的例子。我已经提供了一个可以被应用程序用来构建可视化树显示的查询。另外请注意,简单的树示例(每个父母不超过两个孩子)可能不太现实,并且当单个父母存在许多孩子时,显示将变得难以构建并且不令人满意。

+0

这只是一个递归的表(对自己?)。这将需要我一段时间,但我会筛选此...我没有给你任何信息,因为我想保持在高水平。他们都通过代理键加入,我认为这将是所有你需要的。谢谢,我会尽快回复您。 – Nix 2010-07-30 13:26:48

+0

这对我来说没用......你用同一张表吗?我有3个联合表我正在加入... – Nix 2010-08-03 19:29:54

+0

@Nix,我说'你不提供任何表结构,所以这里是一个处理树结构的递归CTE的示例',关键词'sample'。如果您希望剪切并粘贴答案,您需要在您的问题中提供**方式更多**详细信息。如果你真的需要这个问题的答案,你应该为你的表提供等效的DECLARE和INSERT语句,就像我在上面的代码中一样,以及你想要的那个样例数据的结果集。除此之外,没有答案可以成为你想要的,不可能猜测你的表格结构并且阅读你想要的东西。 – 2010-08-04 11:30:54