如何在WITH..AS块中包含变量?

时间:2019-08-09 13:49:07

标签: sql sql-server

我有每个员工主要和次要职能的查询:

DECLARE @mainFunctionId INT

SELECT TOP 1 
    @mainFunctionId = FunctionId 
FROM 
    (SELECT 
         [le].[EmployeeId], [le].[FunctionId],[le].[Label], 
         ROW_NUMBER() OVER (PARTITION BY [le].[EmployeeId] ORDER BY [le].[SortOrder] ASC) AS [RealOrder] 
     FROM 
         (SELECT 
              [e].[EmployeeId], [es].[FunctionId], ef.Label, ISNULL([es].[SortOrder], 9999) AS [SortOrder]
          FROM 
              [Employee] [e] 
          INNER JOIN 
              [Employee_Scope] AS [es] ON [es].[EmployeeId] = [e].[EmployeeId] 
          INNER JOIN
              [Employee_Function] AS [ef] ON es.FunctionId = ef.FunctionId) [le]) [emp]

SELECT DISTINCT 
    [emp].[EmployeeId], [emp].[FunctionId],[emp].Label, IIF(@mainFunctionId = emp.FunctionId,'main','secondary')
FROM 
    (SELECT 
         [le].[EmployeeId], [le].[FunctionId], [le].[Label], 
         ROW_NUMBER() OVER(PARTITION BY [le].[EmployeeId] ORDER BY [le].[SortOrder] ASC) AS [RealOrder] 
     FROM 
         (SELECT 
              [e].[EmployeeId], [es].[FunctionId],ef.Label, ISNULL([es].[SortOrder], 9999) AS [SortOrder]
          FROM 
              [Employee] [e] 
          INNER JOIN 
              [Employee_Scope] AS [es] ON [es].[EmployeeId] = [e].[EmployeeId] 
          INNER JOIN 
              [Employee_Function] AS [ef] ON es.FunctionId = ef.FunctionId) [le]) [emp]

输出:
enter image description here
我想将先前的查询集成到我维度的源查询中:

SELECT 
    [E].[EmployeeId], [E].[AdminFileId], [E].[Lastname] + ' ' + [E].[Firstname] AS [Name], [ES][Status]
FROM 
    [Employee] AS [E] 
INNER JOIN 
    [EmployeeStatus] AS [ES] ON [ES].[EmployeeStatusId] = [E].[EmployeeStatusId]

我的预期输出为(对于拥有EmployeeId = 1的员工):

EmployeeId  AdminFileId  Name       Status Label                     
-----------------------------------------------------------------------
1           23544        Marco Polo IN     Manager        main 
1           23544        Marco Polo IN     Senior  Account secondary 
1           23544        Marco Polo IN     Office Manager secondary

2 个答案:

答案 0 :(得分:1)

当你说:

  

如何在块中包含变量

您是否在问如何为每个员工使用@mainFunctionId?也许当您提到“ with ... as”时,是否暗示您认为CTE是可行的方式?

如果是这样,我将完全摆脱多变的心态。此外,在您的第一个查询中,您不会透露要获得顶级商品的订购顺序。但是,由于其中包含“ RealOrder”列,所以我想这是您的意图。

下面,我简化了您的第二个查询。您使用row_number可以否定“ Distinct”。不需要它,或者,如果需要的话,您必须对查询进行重新处理。不需要嵌套子查询以围绕排序顺序生成isull。您可以更直接一些,只需在row_number函数中创建它即可。其他简化只是样式问题。

简化之后,我将核心查询简单地包装到CTE中,并从引用查询中利用先前计算的realOrder列来标识主记录和辅助记录。

with

    employeeScopeFunctions as (

        select      e.employeeId, 
                    es.FunctionId,
                    ef.Label, 

                    realOrder = row_number() over(
                        partition by le.employeeId
                        order by isnull(es.sortOrder, 9999)
                    )

        from        employee e 
        join        employee_scope es on es.employeeId = e.employeeId
        join        employee_function ef on es.FunctionId = ef.FunctionId

    )

    select      *,
                primacy = iif(realOrder = 1, 'main', 'secondary')
    from        employeeScopeFunctions

答案 1 :(得分:1)

我认为您的查询可以简化为:

SELECT *, 
  CASE WHEN ROW_NUMBER() OVER(PARTITION BY e.Id ORDER BY COALESE(es.SortOrder, 9999)) = 1 THEN 'main' ELSE 'secondary' END
FROM 
  Employee e
  INNER JOIN Employee_Scope es ON es.EmployeeId = e.EmployeeId
  INNER JOIN Employee_Function ef ON es.FunctionId = ef.FunctionId

这会将您所有的员工数据连接在一起。 row_number根据SortOrder的顺序建立一个递增计数器。对于每个不同的员工ID,该数字从1重新开始(这是by by子句的用途),这决定了每个员工如何可以拥有一个主要员工,然后具有多个第二员工