Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 在T-SQL存储过程中使用空格缩进记录_Sql Server 2008_Tsql_Stored Procedures - Fatal编程技术网

Sql server 2008 在T-SQL存储过程中使用空格缩进记录

Sql server 2008 在T-SQL存储过程中使用空格缩进记录,sql-server-2008,tsql,stored-procedures,Sql Server 2008,Tsql,Stored Procedures,我有一个存储过程,它根据部门ID返回记录: Employee Name ManagerID SupervisorID ID John Smith 1 1 1 Tom Jones 1 2

我有一个存储过程,它根据部门ID返回记录:

Employee Name                ManagerID         SupervisorID                ID  
    John Smith                  1                     1                      1  
    Tom Jones                   1                     2                      2  
    Robert Thompson             1                     2                      3
    Jennifer Stevens            1                     4                      4  
我想缩进返回的记录,如下所示:

  • 如果ManagerID=ID(无缩进)
  • 如果SupervisorID=ID(缩进2个空格)
  • Else(缩进4个空格)*
比如:

John Smith  
   Tom Jones  
       Robert Thompson  
   Jennifer Stevens
我如何做到这一点?

使用案例陈述

EmployeeName = 
    CASE ManagerID
        WHEN 1 THEN [Employee Name]
        WHEN 2 THEN '  ' + [Employee Name]
        ELSE '    ' + [Employee Name]
    END 
(注:伪代码,未测试)

编辑:从
结束案例
中删除
案例

CREATE TABLE Employee
 (EmployeeID int,
  EmployeeName nvarchar(25),
  ManagerID int)
;

INSERT INTO Employee
VALUES (1, 'John Smith', 1)
;

INSERT INTO Employee
VALUES (2, 'Bill Gates', 2)
;

INSERT INTO Employee
VALUES (3, 'Adam Smith', 2)
;

INSERT INTO Employee
VALUES (4, 'John Gates', 3)
;

INSERT INTO Employee
VALUES (5, 'Jake Smith', 4)
;

SELECT 
  EmployeeName = 
    CASE ManagerID
      WHEN 1 THEN EmployeeName
      WHEN 2 THEN '  ' + EmployeeName
      ELSE '    ' + EmployeeName
    END 
FROM Employee
输出:

EmployeeName
-----------------------------
John Smith
  Bill Gates
  Adam Smith
    John Gates
    Jake Smith
使用案例陈述

EmployeeName = 
    CASE ManagerID
        WHEN 1 THEN [Employee Name]
        WHEN 2 THEN '  ' + [Employee Name]
        ELSE '    ' + [Employee Name]
    END 
(注:伪代码,未测试)

编辑:从
结束案例
中删除
案例

CREATE TABLE Employee
 (EmployeeID int,
  EmployeeName nvarchar(25),
  ManagerID int)
;

INSERT INTO Employee
VALUES (1, 'John Smith', 1)
;

INSERT INTO Employee
VALUES (2, 'Bill Gates', 2)
;

INSERT INTO Employee
VALUES (3, 'Adam Smith', 2)
;

INSERT INTO Employee
VALUES (4, 'John Gates', 3)
;

INSERT INTO Employee
VALUES (5, 'Jake Smith', 4)
;

SELECT 
  EmployeeName = 
    CASE ManagerID
      WHEN 1 THEN EmployeeName
      WHEN 2 THEN '  ' + EmployeeName
      ELSE '    ' + EmployeeName
    END 
FROM Employee
输出:

EmployeeName
-----------------------------
John Smith
  Bill Gates
  Adam Smith
    John Gates
    Jake Smith
那么:

SPACE (
CASE
  WHEN ManagerID = ID THEN 0
  WHEN SupervisorID = ID THEN 2
  ELSE 4
  END
) + [Employee Name] AS [Employee Name]
那么:

SPACE (
CASE
  WHEN ManagerID = ID THEN 0
  WHEN SupervisorID = ID THEN 2
  ELSE 4
  END
) + [Employee Name] AS [Employee Name]

如果您想允许任意数量的级别(例如,每个人只是一个老板,然后可以是任何深度),您必须使用递归CTE。此外,可能需要编写查询,以便根据关系正确地重新排序(这样,在示例数据中,Robert的行始终显示在Tom之后,而不是第一行或任何其他人之后)

展示这是如何工作的;我增加了一些人使它更有趣

WITH EmployeeHierarchy AS (
  SELECT
    0 [Level],
    CAST(1 AS float) [Step],
    CAST(ROW_NUMBER() OVER (ORDER BY e.ID) AS float) [Sort],
    e.*
    FROM Employee e
    WHERE e.BossID IS NULL
  UNION ALL
  SELECT
    h.[Level]+1,
    h.[Step]/(SUM(1) OVER ()+1),
    h.[Sort]+(ROW_NUMBER() OVER (ORDER BY e.ID))*(h.[Step]/(SUM(1) OVER ()+1)),
    e.*
    FROM Employee e
    JOIN EmployeeHierarchy h ON (h.ID = e.BossID)
)
SELECT SPACE(h.Level*2)+h.Name [Employee Name], h.BossID, h.ID
  FROM EmployeeHierarchy h
  ORDER BY h.Sort

如果您想允许任意数量的级别(例如,每个人只是一个老板,然后可以是任何深度),您必须使用递归CTE。此外,可能需要编写查询,以便根据关系正确地重新排序(这样,在示例数据中,Robert的行始终显示在Tom之后,而不是第一行或任何其他人之后)

展示这是如何工作的;我增加了一些人使它更有趣

WITH EmployeeHierarchy AS (
  SELECT
    0 [Level],
    CAST(1 AS float) [Step],
    CAST(ROW_NUMBER() OVER (ORDER BY e.ID) AS float) [Sort],
    e.*
    FROM Employee e
    WHERE e.BossID IS NULL
  UNION ALL
  SELECT
    h.[Level]+1,
    h.[Step]/(SUM(1) OVER ()+1),
    h.[Sort]+(ROW_NUMBER() OVER (ORDER BY e.ID))*(h.[Step]/(SUM(1) OVER ()+1)),
    e.*
    FROM Employee e
    JOIN EmployeeHierarchy h ON (h.ID = e.BossID)
)
SELECT SPACE(h.Level*2)+h.Name [Employee Name], h.BossID, h.ID
  FROM EmployeeHierarchy h
  ORDER BY h.Sort

您最好在
SupervisorID
上创建一个递归CTE匹配,该匹配将适用于任意深度。这是您在SQL中不应该做的事情,这是应用程序代码应该处理的事情。您最好在
SupervisorID
上创建一个递归CTE匹配,这将适用于任意深度。这是SQL中不应该做的事情,这是应用程序代码应该处理的事情。嗯,ID 2是比尔盖茨,所以为了有意义亚当·斯密应该再缩进一个,不是吗?嗯,ID 2是比尔盖茨,所以为了有意义亚当·斯密应该再缩进一个,没有?谢谢你的Fiddler链接。REPLICATE()是我正在寻找的函数。帮助我避免了许多不必要的代码。感谢Fiddler链接。REPLICATE()是我正在寻找的函数。帮助我避免了许多不必要的代码。