请不要给我指向如何创建树结构或SQL中的CTE的文章,我已经读了很多!!! 对于内心深处的t-sql来说,这可能并不那么困难,但对我来说绝对是困难的:)。
这里是情况,我必须创建一个报告,看起来像这样: alt text http://img85.imageshack.us/img85/6372/70337249.png 当我的存储过程(SQL Server sproc)的参数设置为“全部”时,这非常有效,因为它只获取所有数据,最终用户可以展开/折叠项目以查看层次结构。 当我运行报告并选择一个名称(例如在此处的“Kevin Bicking”)时,问题就会发生,请参见结果: alt text http://img69.imageshack.us/img69/8398/46964880.png 这个问题在于我只得到了Kevin的直接报告,但实际上我需要看到所有的下属。例如,在第一张图片中,我希望我的报告显示Kevin以下的所有人,以及Kelvin和Tim以下的所有人等等。
我理解这个问题,但不知道如何在T-SQL中处理它。这是我的存储过程:
该存储过程运行良好,没有错误,但我的问题是如何使用我在此处列出的字段来更改它,以便按照我上面所描述的方式获取直接报告给每个人的下属。基本上,EmployeeName字段是每次的顶级(即报告参数),ReportsTo别名是您在图像中看到的报告字段。
我没有关于SSRS报告的问题,只是想知道如何修改查询,使得在这种情况下,如果我选择Kevin Bicking并将其传递给我的存储过程。它目前仅返回直接员工Kelvin Squires。但我想要的不仅仅是Kelvin,还有所有报告给Kelvin的人,以及可能是Kelvin下属的老板,但也有直接报告。
非常感谢任何帮助。谢谢你的时间!
编辑部分 我正在使用sql server 2005。有人要求表定义,请注意,我没有创建这个表,它是基于CRM的系统自动生成的:
这里是情况,我必须创建一个报告,看起来像这样: alt text http://img85.imageshack.us/img85/6372/70337249.png 当我的存储过程(SQL Server sproc)的参数设置为“全部”时,这非常有效,因为它只获取所有数据,最终用户可以展开/折叠项目以查看层次结构。 当我运行报告并选择一个名称(例如在此处的“Kevin Bicking”)时,问题就会发生,请参见结果: alt text http://img69.imageshack.us/img69/8398/46964880.png 这个问题在于我只得到了Kevin的直接报告,但实际上我需要看到所有的下属。例如,在第一张图片中,我希望我的报告显示Kevin以下的所有人,以及Kelvin和Tim以下的所有人等等。
我理解这个问题,但不知道如何在T-SQL中处理它。这是我的存储过程:
CREATE PROCEDURE [dbo].[rptContactsHierarchy]
@ContactID varchar(100)='All'
AS
BEGIN
SET NOCOUNT ON;
SELECT
c1.id AS EmployeeID,
c2.id as ManagerID,
c1.first_name + ' ' + c1.last_name AS [EmployeeName],
c1.title AS Title,
c2.first_name + ' ' + c2.last_name AS [ReportsTo]
FROM
Contacts c1
INNER JOIN
Contacts c2
ON
c1.reports_to_id = c2.id
WHERE
c1.deleted=0
AND (@ContactID='All' OR (c2.first_name + ' ' + c2.last_name = @ContactID OR (c1.first_name + ' ' + c1.last_name = @ContactID)))
END
该存储过程运行良好,没有错误,但我的问题是如何使用我在此处列出的字段来更改它,以便按照我上面所描述的方式获取直接报告给每个人的下属。基本上,EmployeeName字段是每次的顶级(即报告参数),ReportsTo别名是您在图像中看到的报告字段。
我没有关于SSRS报告的问题,只是想知道如何修改查询,使得在这种情况下,如果我选择Kevin Bicking并将其传递给我的存储过程。它目前仅返回直接员工Kelvin Squires。但我想要的不仅仅是Kelvin,还有所有报告给Kelvin的人,以及可能是Kelvin下属的老板,但也有直接报告。
非常感谢任何帮助。谢谢你的时间!
编辑部分 我正在使用sql server 2005。有人要求表定义,请注意,我没有创建这个表,它是基于CRM的系统自动生成的:
USE [sugarcrm]
GO
/****** Object: Table [dbo].[contacts] Script Date: 07/22/2010 10:44:31 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING OFF
GO
CREATE TABLE [dbo].[contacts](
[id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[date_entered] [datetime] NULL,
[date_modified] [datetime] NULL,
[modified_user_id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[created_by] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[description] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[deleted] [bit] NULL DEFAULT ('0'),
[assigned_user_id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[team_id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[salutation] [varchar](5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[first_name] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[last_name] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[title] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[department] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[do_not_call] [bit] NULL DEFAULT ('0'),
[phone_home] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[phone_mobile] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[phone_work] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[phone_other] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[phone_fax] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[primary_address_street] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[primary_address_city] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[primary_address_state] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[primary_address_postalcode] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[primary_address_country] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[alt_address_street] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[alt_address_city] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[alt_address_state] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[alt_address_postalcode] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[alt_address_country] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[assistant] [varchar](75) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[assistant_phone] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[lead_source] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[reports_to_id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[birthdate] [datetime] NULL,
[portal_name] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[portal_active] [bit] NOT NULL DEFAULT ('0'),
[portal_password] [varchar](32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[portal_app] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[campaign_id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [pk_contacts] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
解决方案
在这里得到大家的帮助后,我找到了解决方案。
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[rptContactsHierarchy]
@ContactID varchar(100)='All'
AS
BEGIN
SET NOCOUNT ON;
--grab id of @contactid
DECLARE @Test varchar(36)
SELECT @Test = (SELECT id FROM contacts c1 WHERE c1.first_name + ' ' + c1.last_name = @ContactID)
;WITH StaffTree AS
(
SELECT
c.id,
c.Title,
c.first_name,
c.last_name,
c.reports_to_id,
c.reports_to_id as Manager_id,
cc.first_name AS Manager_first_name,
cc.last_name as Manager_last_name,
cc.first_name + ' ' + cc.last_name AS [ReportsTo],
c.first_name + ' ' + c.last_name as EmployeeName,
1 AS LevelOf
FROM Contacts c
LEFT OUTER JOIN Contacts cc ON c.reports_to_id=cc.id
WHERE c.id=@Test OR (@Test IS NULL AND c.reports_to_id IS NULL)
UNION ALL
SELECT
s.id,
s.Title,
s.first_name,
s.last_name,
s.reports_to_id,
t.id,
t.first_name,
t.last_name,
t.first_name + ' ' + t.last_name,
s.first_name + ' ' + s.last_name,
t.LevelOf+1
FROM StaffTree t
INNER JOIN Contacts s ON t.id=s.reports_to_id
WHERE s.reports_to_id=@Test OR @Test IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree
END