SQL Server父子(父母看到所有的一切)?

时间:2016-12-21 09:01:21

标签: sql-server tsql parent-child hierarchy

这是我的表:

EmployeeID  Employee    ManagerID
---------------------------------
    1       Anna           5
    2       John           4
    3       Steve          4
    4       Lisa           1
    5       Adam          NULL
    6       Per            1

我可以通过以下方式与自我联接获得父子关系:

SELECT 
    E.EmployeeID,
    E.Employee AS Employee,
    E.ManagerID,
    M.Employee AS Manager
FROM 
    Employee AS E
LEFT JOIN 
    Employee AS M ON E.ManagerID = M.EmployeeID

EmployeeID  Employee    ManagerID   Manager
1   Anna    5   Adam
2   John    4   Lisa
3   Steve   4   Lisa
4   Lisa    1   Anna
5   Adam    NULL NULL
6   Per     1    Anna

但是,我将如何确保父级看到整个层次结构级别?

我希望桌子看起来像这样:

EmployeeID  Manager Employee    EmployeeID  
5   Adam    Anna    1
5   Adam    Per     6
5   Adam    Lisa    4
5   Adam    John    2
5   Adam    Steve   3
1   Anna    Per     6
1   Anna    Lisa    4
1   Anna    John    2
1   Anna    Steve   3
4   Lisa    John    2
4   Lisa    Steve   3

注意:在这个例子中我只有3个级别的马槽,但可以有更多

2 个答案:

答案 0 :(得分:2)

你可以试试这个:

User www-data
Group www-data
ErrorLog /proc/self/fd/2

IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf

Listen 80
DocumentRoot /var/www/html/web
<Directory /var/www/html/web>
    AllowOverride None
    Order Allow,Deny
    Allow from All

    <IfModule mod_rewrite.c>
        Options -MultiViews
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ app.php [QSA,L]
    </IfModule>
</Directory>

AccessFileName .htaccess
<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

DirectoryIndex disabled
DirectoryIndex app.php

enter image description here

我们正在使用递归CTE,如果您第一次看到这种语法,它可能看起来有点混乱和复杂,但它并没有什么特别之处。

何时使用递归CTE运行一些性能测试,以确保它是解决问题的正确方法。

答案 1 :(得分:1)

您应该使用递归CTE语法。在第一次迭代中(在UNION ALL之前),您将获得所有父子对。在递归部分(在UNION ALL之后),您将获得每对的下一级子项,并将其替换为父子项对,而不是将父项保留为父项。

WITH CTE AS 
(
   SELECT TP.EmployeeID as ManagerId, 
          TP.Employee as Manager,
          TC.EmployeeID as EmployeeID, 
          TC.Employee as Employee

          FROM TEmployee as TP
          JOIN TEmployee as TC on (TP.EmployeeID = TC.ManagerID)

          UNION ALL

   SELECT TP.ManagerId as ManagerId, 
          TP.Manager as Manager,
          TC.EmployeeID as EmployeeID, 
          TC.Employee as Employee

          FROM CTE as TP
          JOIN TEmployee as TC on (TP.EmployeeID = TC.ManagerID)
)
SELECT * FROM CTE Order By ManagerID

结果:

+-----------+---------+------------+----------+
| ManagerId | Manager | EmployeeID | Employee |
+-----------+---------+------------+----------+
|         1 | Anna    |          4 | Lisa     |
|         1 | Anna    |          6 | Per      |
|         1 | Anna    |          2 | John     |
|         1 | Anna    |          3 | Steve    |
|         4 | Lisa    |          2 | John     |
|         4 | Lisa    |          3 | Steve    |
|         5 | Adam    |          1 | Anna     |
|         5 | Adam    |          4 | Lisa     |
|         5 | Adam    |          6 | Per      |
|         5 | Adam    |          2 | John     |
|         5 | Adam    |          3 | Steve    |
+-----------+---------+------------+----------+