Sql 复杂存储过程
我是sql方面的新手,我正在尝试创建一个相当复杂的存储过程,用于在Visual Studio的Business Intelligence中使用sql reporting services创建的报表 我有一个主“Project”表,它通过使用链接表(我的存储过程中感兴趣的是“Status”、“Facility”和“Branch”)链接其他各种表。申请所做的是研究人员提交一个项目,并通过以下审批流程: 专业健康经理>分公司负责人>健康管理团队 为了简化此审批流程,另一名团队成员开发了一个自定义工作流解决方案,该解决方案利用了“WorkflowHistory”表。此表中的内容(除其他外)包括ProjectId、WorkflowStep和执行工作流步骤的日期,以及执行该步骤的人员发布的注释。我想在我的报告中包括以下内容: 我在报告中需要的信息如下: “ProjectId”和“Title”来自“Project”表。“设施”、“分支机构”和“状态”从链接到“项目”的表中删除Received'需要为项目执行初始工作流步骤的日期。“结束”需要是为项目执行最终工作流步骤的日期。“注释”必须是留给最后一个工作流步骤的注释 因此,报告中每一行的数据来自以下位置:Sql 复杂存储过程,sql,stored-procedures,join,sql-server-2012,subquery,Sql,Stored Procedures,Join,Sql Server 2012,Subquery,我是sql方面的新手,我正在尝试创建一个相当复杂的存储过程,用于在Visual Studio的Business Intelligence中使用sql reporting services创建的报表 我有一个主“Project”表,它通过使用链接表(我的存储过程中感兴趣的是“Status”、“Facility”和“Branch”)链接其他各种表。申请所做的是研究人员提交一个项目,并通过以下审批流程: 专业健康经理>分公司负责人>健康管理团队 为了简化此审批流程,另一名团队成员开发了一个自定义工作流
- “项目”中的一行
- “分行”的一行
- “状态”中的一行
- 来自“Facility”的多行(在下面的运行尝试中,我仅返回子查询中的第一个Facility,但我希望所有分配给项目的Facility都以逗号分隔)
- “WorkflowHistory”中的两行不同
- 起始日期-获取特定日期后收到的所有报告(这将是“WorkflowHistory”中第一个工作流步骤的“ActionOn”)
- 截止日期-获取特定日期之前收到的所有报告(这将是“WorkflowHistory”中最后一个工作流步骤的“ActionOn”)
- 状态-筛选具有特定状态的项目
- 分支-筛选指定给特定分支的项目
- 日期范围筛选不起作用
- I只能返回子查询中的第一个工具 (以下是评论整个WHERE部分时仍然存在的问题)
- 项目的最后一个工作流步骤可能是2到5之间的任何一个步骤,这取决于它是否被批准以及何时被拒绝。我需要弄清楚如何获得“结束”日期以及在这一步上留下的评论
- 我在参数中传递“状态”。我需要弄清楚如何按一种状态或所有状态(实际上不是所有状态,但最后3种状态是“批准”、“拒绝”和“结束”)提交文件。分支机构也一样
CREATE PROCEDURE [dbo].[stp_CityHealthResearchRequestsReport]
@FromDate DATETIME,
@ToDate DATETIME,
@StatusId int,
@BranchId int,
@Count INT OUTPUT
AS
BEGIN
DECLARE @TempTable TABLE
(
ProjectId INT,
Recieved DATETIME,
Concluded DATETIME,
Comment VARCHAR(8000)
)
IF @StatusId <> 0 AND @BranchId <> 0
BEGIN
INSERT INTO @TempTable (ProjectId, Recieved, Concluded, Comment)
SELECT DISTINCT
p.ProjectId,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 1
ORDER BY wf.WorkflowHistoryId DESC) AS Recieved,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Concluded,
(SELECT TOP 1 wf.Comment
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Comment
FROM
Project p
JOIN WorkflowHistory w ON p.ProjectId = w.ProjectId
JOIN ProjectBranch pb ON pb.ProjectId = p.ProjectId
WHERE
p.ProjectId = w.ProjectId
AND p.StatusId = @StatusId
AND pb.BranchId = @BranchId
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
SELECT DISTINCT
p.ProjectId,
p.Title,
STUFF (
(SELECT ', ' + f.Name
FROM dbo.Facility f
LEFT JOIN dbo.ProjectFacility pf ON f.FacilityId = pf.FacilityId
WHERE pf.ProjectId = p.ProjectId
FOR XML PATH (''))
, 1, 1, '') AS Facilities,
tt.Recieved,
tt.Concluded,
b.BranchName,
st.Description AS StatusText,
tt.Comment,
tt.Concluded - tt.Recieved AS Turnaround
FROM
dbo.Project p
INNER JOIN @TempTable tt ON p.ProjectId = tt.ProjectId
LEFT JOIN dbo.ProjectBranch pb ON p.ProjectId = pb.ProjectId
LEFT JOIN dbo.Branch b ON pb.BranchId = b.BranchId
LEFT JOIN dbo.Status st ON p.StatusId = st.StatusId
WHERE
p.StatusId = @StatusId
AND b.BranchId = @BranchId
SET @Count = @@ROWCOUNT
END
IF @StatusId <> 0 AND @BranchId = 0
BEGIN
INSERT INTO @TempTable (ProjectId, Recieved, Concluded, Comment)
SELECT DISTINCT
p.ProjectId,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 1
ORDER BY wf.WorkflowHistoryId DESC) AS Recieved,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Concluded,
(SELECT TOP 1 wf.Comment
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Comment
FROM
Project p
JOIN WorkflowHistory w ON p.ProjectId = w.ProjectId
JOIN ProjectBranch pb ON pb.ProjectId = p.ProjectId
WHERE
p.ProjectId = w.ProjectId
AND p.StatusId = @StatusId
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
SELECT DISTINCT
p.ProjectId,
p.Title,
STUFF (
(SELECT ', ' + f.Name
FROM dbo.Facility f
LEFT JOIN dbo.ProjectFacility pf ON f.FacilityId = pf.FacilityId
WHERE pf.ProjectId = p.ProjectId
FOR XML PATH (''))
, 1, 1, '') AS Facilities,
tt.Recieved,
tt.Concluded,
b.BranchName,
st.Description AS StatusText,
tt.Comment,
tt.Concluded - tt.Recieved AS Turnaround
FROM
dbo.Project p
INNER JOIN @TempTable tt ON p.ProjectId = tt.ProjectId
LEFT JOIN dbo.ProjectBranch pb ON p.ProjectId = pb.ProjectId
LEFT JOIN dbo.Branch b ON pb.BranchId = b.BranchId
LEFT JOIN dbo.Status st ON p.StatusId = st.StatusId
WHERE
p.StatusId = @StatusId
SET @Count = @@ROWCOUNT
END
IF @StatusId = 0 AND @BranchId <> 0
BEGIN
INSERT INTO @TempTable (ProjectId, Recieved, Concluded, Comment)
SELECT DISTINCT
p.ProjectId,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 1
ORDER BY wf.WorkflowHistoryId DESC) AS Recieved,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Concluded,
(SELECT TOP 1 wf.Comment
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Comment
FROM
Project p
JOIN WorkflowHistory w ON p.ProjectId = w.ProjectId
JOIN ProjectBranch pb ON pb.ProjectId = p.ProjectId
WHERE
p.ProjectId = w.ProjectId
AND p.StatusId = 5
AND pb.BranchId = @BranchId
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
OR p.ProjectId = w.ProjectId
AND p.StatusId = 6
AND pb.BranchId = @BranchId
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
OR p.ProjectId = w.ProjectId
AND p.StatusId = 7
AND pb.BranchId = @BranchId
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
SELECT DISTINCT
p.ProjectId,
p.Title,
STUFF (
(SELECT ', ' + f.Name
FROM dbo.Facility f
LEFT JOIN dbo.ProjectFacility pf ON f.FacilityId = pf.FacilityId
WHERE pf.ProjectId = p.ProjectId
FOR XML PATH (''))
, 1, 1, '') AS Facilities,
tt.Recieved,
tt.Concluded,
b.BranchName,
st.Description AS StatusText,
tt.Comment,
tt.Concluded - tt.Recieved AS Turnaround
FROM
dbo.Project p
INNER JOIN @TempTable tt ON p.ProjectId = tt.ProjectId
LEFT JOIN dbo.ProjectBranch pb ON p.ProjectId = pb.ProjectId
LEFT JOIN dbo.Branch b ON pb.BranchId = b.BranchId
LEFT JOIN dbo.Status st ON p.StatusId = st.StatusId
WHERE
p.StatusId = 5
AND pb.BranchId = @BranchId
OR p.StatusId = 6
AND pb.BranchId = @BranchId
OR p.StatusId = 7
AND pb.BranchId = @BranchId
SET @Count = @@ROWCOUNT
END
IF @StatusId = 0 AND @BranchId = 0
BEGIN
INSERT INTO @TempTable (ProjectId, Recieved, Concluded, Comment)
SELECT DISTINCT
p.ProjectId,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 1
ORDER BY wf.WorkflowHistoryId DESC) AS Recieved,
(SELECT TOP 1 wf.ActionedOn
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Concluded,
(SELECT TOP 1 wf.Comment
FROM WorkflowHistory wf
WHERE wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 4
OR wf.ProjectId = p.ProjectId
AND wf.WorkflowStep = 5
ORDER BY wf.WorkflowHistoryId DESC) AS Comment
FROM
Project p
JOIN WorkflowHistory w ON p.ProjectId = w.ProjectId
JOIN ProjectBranch pb ON pb.ProjectId = p.ProjectId
WHERE
p.ProjectId = w.ProjectId
AND p.StatusId = 5
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
OR p.ProjectId = w.ProjectId
AND p.StatusId = 6
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
OR p.ProjectId = w.ProjectId
AND p.StatusId = 7
AND w.WorkflowStep = 1
AND (w.ActionedOn BETWEEN @FromDate AND @ToDate)
SELECT DISTINCT
p.ProjectId,
p.Title,
STUFF (
(SELECT ', ' + f.Name
FROM dbo.Facility f
LEFT JOIN dbo.ProjectFacility pf ON f.FacilityId = pf.FacilityId
WHERE pf.ProjectId = p.ProjectId
FOR XML PATH (''))
, 1, 1, '') AS Facilities,
tt.Recieved,
tt.Concluded,
b.BranchName,
st.Description AS StatusText,
tt.Comment,
tt.Concluded - tt.Recieved AS Turnaround
FROM
dbo.Project p
INNER JOIN @TempTable tt ON p.ProjectId = tt.ProjectId
LEFT JOIN dbo.ProjectBranch pb ON p.ProjectId = pb.ProjectId
LEFT JOIN dbo.Branch b ON pb.BranchId = b.BranchId
LEFT JOIN dbo.Status st ON p.StatusId = st.StatusId
WHERE
p.StatusId = 5
OR p.StatusId = 6
OR p.StatusId = 7
SET @Count = @@ROWCOUNT
END
END
创建过程[dbo]。[stp_城市健康研究请求报告]
@FromDate日期时间,
@今天的日期时间,
@StatusId int,
@布朗希德国际酒店,
@计数整数输出
像
开始
声明@attreable表
(
投射INT,
收到日期时间,
结束日期时间,
VARCHAR评论(8000)
)
如果@StatusId 0和@BranchId 0
开始
插入@tentable(项目、接收、结束、评论)
选择不同的
p、 投射的,
(选择顶部1 wf.ActionOn
来自WorkflowHistory wf
其中wf.ProjectId=p.ProjectId
和wf.WorkflowStep=1
已收到wf.WorkflowHistoryId DESC)的订单,
(选择顶部1 wf.ActionOn
来自WorkflowHistory wf
其中wf.ProjectId=p.ProjectId
和wf.WorkflowStep=4
或wf.ProjectId=p.ProjectId
和wf.WorkflowStep=5
由wf.WorkflowHistoryId DESC)完成的订单,
(选择顶部1 wf.注释
来自WorkflowHistory wf
其中wf.ProjectId=p.ProjectId
和wf.WorkflowStep=4
或wf.ProjectId=p.ProjectId
和wf.WorkflowStep=5
按wf.WorkflowHistoryId DESC)排序作为注释
从…起
项目p
在p.projectd=w.projectd上连接工作流历史记录w
在pb.projectd=p.projectd上连接ProjectBranch pb
哪里
p、 projectd=w.projectd
p.StatusId=@StatusId
和pb.BranchId=@BranchId
w.WorkflowStep=1
和(w.在@FromDate和@ToDate之间采取行动)
选择不同的
p、 投射的,
p、 头衔,
东西(
(选择“,”+f.名称
来自dbo.设施f
左连接f.FacilityId=pf.FacilityId上的dbo.ProjectFacility pf
其中pf.projectd=p.projectd
对于XML路径(“”))
,1,1,,)作为设施,
收到,
tt.总结道,
b、 布兰奇纳姆,
st.描述为状态文本,
tt.评论,
tt.结束-tt.作为周转收到
从…起
dbo.p项目
p.projectd=tt.projectd上的内部连接@attable tt
p.projectd=pb.projectd上的左连接dbo.ProjectBranch pb
在pb.BranchId=b.BranchId上左连接dbo.Branch b
左连接dbo.Status st ON p.StatusId=st.StatusId
哪里
p、 StatusId=@StatusId
b.BranchId=@BranchId
设置@Count=@@ROWCOUNT
终止
如果@StatusId 0和@BranchId=0
开始
插入@tentable(ProjectId、received、consulated、Com
-- find out the final step for each project
WITH FinalStep AS
(
SELECT ProjectId, MAX(WorkflowStep) as MaxWorkflowStep
FROM WorkflowHistory
WHERE WorkflowStep > 1
GROUP BY ProjectId
)
SELECT
p.ProjectId,
p.Title,
-- this is ugly consider creating a scalar function to encapsulate it
STUFF (
(SELECT ', ' + f.Name
FROM dbo.Facility f
LEFT JOIN dbo.ProjectFacility pf ON f.FacilityId = pf.FacilityId
WHERE pf.ProjectId = p.ProjectId
FOR XML PATH (''))
, 1, 1, '') AS Facilities,
wf1.ActionedOn AS Recieved,
wf2.ActionedOn AS Concluded,
b.BranchName,
st.Description AS StatusText,
wf2.Comment,
wf2.ActionedOn - w1.ActionedOn AS Turnaround
FROM
Project p
INNER JOIN WorkflowHistory wf1
ON p.ProjectId = wf1.ProjectId
AND wf1.WorkflowStep = 1
LEFT JOIN FinalStep fs
ON fs.ProjectId = p.ProjectId
LEFT JOIN WorkflowHistory wf2
ON p.ProjectId = wf2.ProjectId
AND wf2.WorkflowStep = fs.MaxWorkflowStep
INNER JOIN ProjectBranch pb
ON pb.ProjectId = p.ProjectId
LEFT JOIN dbo.Branch b
ON pb.BranchId = b.BranchId
LEFT JOIN dbo.Status st
ON p.StatusId = st.StatusId
WHERE
p.ProjectId = w.ProjectId
-- IF @StatusId = 0 THEN p.StatusId = 5 or 6 or 7 ELSE p.StatusId = @StatusId
AND ((@StatusId = 0 AND p.StatusId IN (5,6,7)) OR p.StatusId = @StatusId)
-- IF @BranchId = 0 THEN no filter ELSE pb.BranchId = @BranchId
AND (@BranchId = 0 OR pb.BranchId = @BranchId)
AND (wf1.ActionedOn BETWEEN @FromDate AND @ToDate)