2010-09-08 231 views
1

我有以下格式的數據。在SQL Server中創建層次結構

表1

e_id e_name e_type 
------------------------- 
1  CBC  2 
2  ABC  3 
3  N2  1 
4  CBC1 3 
5  ABC1 3 
6  N1  1 

表2

N_ID N_Name 
--------------- 
3  N2 
6  N1 

表3

N_ID E_ID 
------------ 
3  1 
3  2 
3  3 
6  4 
6  5 
6  6 

我想建立一個層次結構如下。

e_id e_name  e_type n_id 
------------------------------------ 
6  N1   1  6 
4  - ABC1  3  6 
5  - CBC1  3  6 
3  N2   1  3 
4  - ABC  3  3 
5  - CBC  2  3 

按節點順序(升序),子節點(升序)。

我試着做一些與此類似,

SELECT u.e_id, 
CASE WHEN e_TYPE_ID = 1 THEN u.e_name ELSE ' - ' + u.e_name END e_name, 
e_TYPE_ID, su.n_ID 
FROM table1 u 
INNER JOIN table3 su on u.e_id = su.e_id 
WHERE EXISTS (SELECT N_ID FROM table2 WHERE N_ID = CASE WHEN u.e_TYPE_ID = 1 THEN u.e_id ELSE n_ID END) 
ORDER BY e_TYPE_ID, u.e_name,n_id 

但我不能得到正確的次序,有沒有更好的方式來做到這一點?

+0

層次結構始終是兩個級別(即,親子,從來沒有祖父母,父母子女)? – 2010-09-08 16:34:09

+0

我沒有找到你?我的也是兩級(N1 -parent,ABC,CBC-孩子) – 2010-09-08 16:43:26

+0

那你就不需要CTE了。 :)你需要從另一個部門去殺死那個DBA。 – 2010-09-08 16:47:12

回答

1

如果您使用SQL Server 2008(或2008 R2),我會建議使用層次ID,如Model Your Data Hierarchies With SQL Server 2008所示。

+1

我認爲這在這個特殊情況下是過分的。 – 2010-09-08 16:35:42

+0

一般來說,很難知道某些東西是否「過度殺傷」,除非您對使用模式,性能特徵等有了一些瞭解。有許多使用層次結構ID概念的成功案例。恕我直言,即使案件很簡單,如果它是正確的方式(tm)做某事,那幾乎總是應該如何做。我支持我的原始建議。 – 2010-09-08 18:02:33

+0

不錯的文章 - 非常有趣。 – Sam 2010-09-09 00:22:27

0

我要把你在正確的道路上,你將需要一個CTE(公共表表達式)來完成這個任務:你爲什麼需要這些麪條

;with EH as 
(
select 1 level, * from Table1 t1 where e_type = 1 
union all 
select level+1, * from EH 
join Table3 t3 on eh.e_id = t3.e_id 
join Table3 t32 on t3.n_id = t32.n_id and t3.e_id 

--FUUUUUUUUUUUUUUUUUUUUU!!!!!!!!!!!!!!1111 

[更新]

無論如何表?你爲什麼不把所有東西放在一張或兩張桌子上?

+0

我知道我也不喜歡它的設計方式,我們使用其他部門數據庫中的表格。 – 2010-09-08 16:38:09

2

用途:

WITH summary AS (
    SELECT a.e_id, 
     a.e_name, 
     a.e_type, 
     b.n_id, 
     CASE WHEN e_type = 1 THEN e_type ELSE 2 END AS rank 
    FROM TABLE1 a 
    JOIN TABLE3 b ON b.e_id = a.e_id) 
    SELECT s.e_id, 
      CASE 
      WHEN s.rank > 1 THEN ' - '+ s.e_name 
      ELSE s.e_name 
      END AS e_name, 
      s.e_type, 
      s.n_id 
    FROM summary s 
ORDER BY s.n_id DESC, s.rank, s.e_name 

我使用測試:

WITH table2 AS (
    SELECT 3 AS n_id, 'N2' AS n_name 
    UNION ALL 
    SELECT 6, 'N1'), 
    table1 AS (
    SELECT 1 AS e_id, 'CBC' AS e_name, 2 AS e_type 
    UNION ALL 
    SELECT 2, 'ABC', 3 
    UNION ALL 
    SELECT 3, 'N2', 1 
    UNION ALL 
    SELECT 4, 'CBC1', 3 
    UNION ALL 
    SELECT 5, 'ABC1', 3 
    UNION ALL 
    SELECT 6, 'N1', 1), 
    table3 AS (
    SELECT 3 AS n_id, 1 AS e_id 
    UNION ALL 
    SELECT 3, 2 
    UNION ALL 
    SELECT 3, 3 
    UNION ALL 
    SELECT 6, 4 
    UNION ALL 
    SELECT 6, 5 
    UNION ALL 
    SELECT 6, 6), 
    summary AS (
    SELECT a.e_id, 
      a.e_name, 
      a.e_type, 
      b.n_id, 
      CASE WHEN e_type = 1 THEN e_type ELSE 2 END AS rank 
    FROM TABLE1 a 
    JOIN TABLE3 b ON b.e_id = a.e_id) 
    SELECT s.e_id, 
     CASE 
      WHEN s.rank > 1 THEN ' - '+ s.e_name 
      ELSE s.e_name 
     END AS e_name, 
     s.e_type, 
     s.n_id 
    FROM summary s 
ORDER BY s.n_id DESC, s.rank, s.e_name 
+0

@Joe Stefanelli:新的,改進的。 – 2010-09-08 18:23:16

+0

我是一個艱難的分級,所以我仍然只是給部分學分。 :-)只有巧合的是,你的'ORDER BY s.n_id DESC ...'讓N1出現在N2之前。在表1中交換N1和N2,以便N1是e_id 3,N2是e_id 6,N2將在N1之前排序。 – 2010-09-08 18:41:53

+0

@Joe Stefanelli:我要求重新計算? =) – 2010-09-08 18:46:48