2010-07-30 35 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