Если бы я следил за вами правильно, вы могли бы сохранить существующий CTE и включить агрегирование в основном запросе.ROW_NUMBER()
можно использовать для ранжирования записей путем увеличения realOrder
.
. Это должно работать в SQL-сервере:
WITH employeeScopeFunctions as (
SELECT
e.employeeId,
es.FunctionId,
ef.Label,
c.CompanyName,
realOrder = row_number() over(partition by e.employeeId order by isnull(es.sortOrder, 9999))
FROM
employee e
LEFT JOIN employee_scope es ON es.employeeId = e.employeeId
LEFT JOIN employee_function ef ON es.FunctionId = ef.FunctionId
LEFT JOIN company c ON es.CompanyId = c.ID
WHERE e.EmployeeId=54
)
SELECT
employeeId,
FunctionId,
Label,
CompanyName = STRING_AGG(CompanyName, ',') WITHIN GROUP (ORDER BY realOrder),
Primacy = CASE ROW_NUMBER() OVER(ORDER BY MIN(realOrder))
WHEN 1 THEN 'primary'
WHEN 2 THEN 'secondary'
WHEN 3 THEN 'tertiary'
END
FROM employeeScopeFunctions
GROUP BY
employeeId,
FunctionId,
Label
Альтернативное решение с дополнительным уровнем вложенности, чтобы избежать вложенностиоконная функция и агрегация:
WITH employeeScopeFunctions as (
SELECT
e.employeeId,
es.FunctionId,
ef.Label,
c.CompanyName,
realOrder = row_number() over(partition by e.employeeId order by isnull(es.sortOrder, 9999))
FROM
employee e
LEFT JOIN employee_scope es ON es.employeeId = e.employeeId
LEFT JOIN employee_function ef ON es.FunctionId = ef.FunctionId
LEFT JOIN company c ON es.CompanyId = c.ID
WHERE e.EmployeeId=54
)
SELECT
employeeId,
FunctionId,
Label,
CompanyName,
Primacy = CASE ROW_NUMBER() OVER(ORDER BY minRealOrder))
WHEN 1 THEN 'primary'
WHEN 2 THEN 'secondary'
WHEN 3 THEN 'tertiary'
END
FROM (
SELECT
employeeId,
FunctionId,
Label,
CompanyName = STRING_AGG(CompanyName, ',') WITHIN GROUP (ORDER BY realOrder),
minRealOrder = MIN(realOrder)
FROM employeeScopeFunctions
GROUP BY
employeeId,
FunctionId,
Label
) x