我有每个员工主要和次要职能的查询:
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]
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
答案 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子句的用途),这决定了每个员工如何可以拥有一个主要员工,然后具有多个第二员工