我们有一个通用的组织表结构,认为它是树或金字塔层次结构。我们基本上有多个想要展示的“树”。在一家公司,一家为另一家公司。
有谁知道显示这些数据的好方法? SQL Query会很好,怀疑它是可能的,但我不反对使用一些OTS工具(最好是免费的)。我还想避免某种类型的报道。我不需要实际的解决方案,只需知道是否可能。所以,如果你说SQL,如果你能给我一个2表的示例,显示一个假,我会很高兴。
结构非常通用
每个表都通过代理键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 int,因为我必须使我的查询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 :(得分:3)
答案 1 :(得分:2)
您没有提供任何表结构,因此这里是一个递归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(''''+@Root_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 c.id=@Root_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 s.reports_to_id=@Root_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(''''+@Root_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 c.id=@Root_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 s.reports_to_id=@Root_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(''''+@Root_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 c.id=@Root_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 s.reports_to_id=@Root_id OR @Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree
输出:
@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的给定表格和数据:
尝试这样的事情:
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
输出:
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-2008
和hierarchical-data
,并且OP希望执行复杂的格式化以显示数据。但是,这种类型的处理和显示不是TSQL的领域,并且是应用程序语言应该处理和格式化SQL查询提供的平面数据的一个非常明确的示例。我提供了一个可以由应用程序用来构建可视树显示的查询。另请注意,简单的树示例(每个父项不超过两个子项)可能不太现实,当单个父项存在多个子项时,显示将变得难以构建且不悦目。
答案 2 :(得分: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
答案 3 :(得分:0)
我相信SQL Server 2008提供了一种新的数据类型来帮助解决这个问题。以下是我认为有用的链接 - http://msdn.microsoft.com/en-us/magazine/cc794278.aspx。我没有在任何评论中看到它,所以希望这有帮助。