如何在存储过程中重用结果以提供给同一存储过程中的第二个选择

时间:2011-02-19 15:56:46

标签: sql sql-server stored-procedures

我正在编写一个存储过程来获取整个屏幕的数据。如何重新使用一个选择的结果进入第二个选择?出于性能原因

简化示例: 我有4张桌子

  1. 负责
  2. 行动(有责任的外键)
  3. 集团(有责任的外键)
  4. 案例(具有外键的组)
  5. 存储过程获取一个caseid来检索数据

    首先选择获取casegroup及其相关responsible记录的详细信息:

    select 
       Case.Date,
       Case.Name,
       Group.Name,
       Responsible.Name
       Responsible.ResponsibleID
    from Case
    inner join Group on Group.GroupID=Case.GroupID
    inner join Responsible on Responsible.ResponsibleID=Group.ResponsibleID
    where CaseID=@CaseID
    

    第二个选择必须获取负责人所分配的所有操作。我们只有caseID,因此我们必须重新构建连接:

    select Action.*  
    from Case
    inner join Group on Group.GroupID=Case.GroupID
    inner join Responsible on Responsible.ResponsibleID=Group.ResponsibleID
    inner join Action  on Action.ResponsibleID=Responsible.ResponsibleID
    where CaseID=@CaseID
    

    如果可以重用上一个结果中的变量,则可以创建以下查询,这可能会更好地提高性能:

    Select * from Action where ResponsibleID={ResultSet1}.ResponsibleID
    

2 个答案:

答案 0 :(得分:5)

考虑将结果保存在表变量中。这将允许您从永久表中对该结果集执行多个SQL操作。

DECLARE @Case TABLE
(
    [CaseDate] datetime,
    [CaseName]  varchar(100),
    [GroupName] varchar(100),
    [ResponsibleName] varchar(100),
    [ResponsibleID] int
)

--get all your case details
INSERT INTO @Case( [CaseDate],[CaseName],
                   [GroupName],[ResponsibleName],[ResponsibleID])
SELECT 
   Case.Date,
   Case.Name,
   Group.Name,
   Responsible.Name
   Responsible.ResponsibleID
FROM      Case
INNER JOIN Group ON Group.GroupID=Case.GroupID
INNER JOIN Responsible ON Responsible.ResponsibleID=Group.ResponsibleID
WHERE CaseID=@CaseID


--now get the Action details for the previous case; 
--are we absolutely sure there is only one row? then an INNER JOIN 
SELECT A.*  
FROM   Action  AS [A] 
INNER JOIN @Case AS C ON A.ResponsibleID=C.ResponsibleID

-- or guard against multiple results in @Case
SELECT A.* FROM Action AS [A] 
WHERE A.ResponsibleID = (SELECT TOP 1 ResponsibleID FROM @Case) 

答案 1 :(得分:3)

如果要同时获取屏幕各个部分的数据,只需运行一个查询即可。是的 - 您将在前导列中获得相同的数据,但这是对两次进入数据库服务器的权衡。

select
   [Case].Date,
   [Case].Name CaseName,
   [Group].Name GroupName,
   Responsible.Name ResponsibleName,
   Responsible.ResponsibleID,
   Action.*
from [Case]
inner join [Group] on [Group].GroupID=[Case].GroupID
inner join Responsible on Responsible.ResponsibleID=[Group].ResponsibleID
inner join Action  on Action.ResponsibleID=Responsible.ResponsibleID
where [Case].CaseID=@CaseID

我注意到有关您的查询的其他事项

  • 案例是保留字。使用不同的名称,但我认为这不是真正的表名称
  • 群组也是保留字。
  • 名称在SELECT子句中多次出现。对它们进行别名,以便前端可以预测地访问它们,而不是使用列位置
  • 如果我们要合并查询,请务必列出Action.*中的列(如果需要,请设置别名),以免与其他列发生冲突