1

我正在研究两个系统之间的集成。在我的课程系统中,有一个对应该是工作人员的讲师的引用。问题是 Courses 系统允许在本地创建讲师记录(我已经有一份工作从我们的 Staff 系统馈送到 Courses 系统)。

一门课程可以有不止一位讲师,出于商业原因,有时会创建本地讲师记录作为占位符。我需要将所有“真正的”讲师连接成一个字符串,但如果为课程设置的任何讲师不是“真正的”讲师,那么我需要输出一个空字符串。也有可能创建课程时没有分配任何讲师。

课程系统

Courses instructorID InstructorName  InstructorOrder
-----------------------------------------------------
ach01   1            Smith           1
ach01   2            Brown           2
phy01   3            James           1
sci01   1            Smith           1
sci01   4            Doe             2
acc01   NULL         NULL            NULL

人员制度

ID   LastName
--------------
1    Smith
2    Brown
3    James

输出

Course  Instructors
-------------------------
arc01   'Smith, Brown'
phy01   'James'
sci01   ''
acc01   ''

这是我想出的 SQL,但我想知道是否有更好的方法来获得相同的结果

select courseID,
       isnull(case max(case when x.rn = 1 then isnull(lastname, '-|-') else '' end) when '-|-' then NULL else max(case when x.rn = 1 then lastname else '' end) end +
              case max(case when x.rn = 2 then isnull(lastname, '-|-') else '' end) when '-|-' then NULL else max(case when x.rn = 2 then ', ' + lastname else '' end) end +
              case max(case when x.rn = 3 then isnull(lastname, '-|-') else '' end) when '-|-' then NULL else max(case when x.rn = 3 then ', ' + lastname else '' end) end +
              case max(case when x.rn = 4 then isnull(lastname, '-|-') else '' end) when '-|-' then NULL else max(case when x.rn = 4 then ', ' + lastname else '' end) end
              , '') Instructors
from (select courseID, s.lastname,
             ROW_NUMBER() over(partition by courseID order by InstructorOrder) rn
      from Courses c left join  
           Active_Staff s on c.instructorID = s.ID 
      ) x
group by courseID
4

2 回答 2

2

这使用了一些不同的语法,但查询基本上与您已有的查询完全相同。我不认为会有性能差异。

select P.Courses,
       case when S.Instructors like '%NOSTAFF%' then '' else S.Instructors end as Instructors
from (
     select C.Courses,
            isnull(S.LastName, 'NOSTAFF') as LastName,
            row_number() over(partition by C.Courses order by C.InstructorOrder) as rn
     from Courses as C
       left outer join Staff as S
         on C.instructorID = S.ID
     ) as T
pivot (
      max(T.LastName) for T.rn in ([1],[2],[3],[4])
      ) as P
cross apply
      (
      select isnull(P.[1], '')+isnull(P.[2], '')+isnull(P.[3], '')+isnull(P.[4], '') as Instructors
      ) as S
于 2013-03-27T17:06:10.127 回答
1

这看起来有点复杂(也许确实如此),但它完成了工作:

;WITH CTE1 AS 
(
    SELECT * FROM Courses c
    LEFT JOIN dbo.Active_Staff s ON c.instructorID = s.ID
)
,CTE2 AS
(  
    SELECT  CourseID, 
        STUFF((SELECT ', ' + LastName 
              FROM   CTE1 c2 
              WHERE  c2.CourseID = c1.CourseID 
              ORDER BY c2.InstructorOrder
              FOR XML PATH('')), 1, 2, '')  LastNames
    FROM  CTE1 c1 
    GROUP BY CourseID
)
SELECT
    CourseID,
    CASE WHEN EXISTS (SELECT * FROM CTE1  WHERE LastName IS NULL AND CTE1.CourseID = Cte2.CourseID) THEN '' ELSE LastNames END AS Instructors
FROM CTE2 

基本上,我们首先将所有字符串连接起来——使用 STUFF 和 FOR XML PATH 组合,然后用空字符串替换那些至少有一个“虚拟”讲师的字符串。

这是SQL Fiddle 演示

于 2013-03-27T17:10:07.373 回答