连接行值sql server 2008 r2

时间:2014-01-24 20:31:22

标签: sql-server-2008 concatenation rows

我有两张桌子registeratt_bottom,我想只显示某个建筑物的学生,这些学生根据今天的日期已经迟到,并用句号分隔句点。 这是连接两个表时数据的显示方式:

 Student ID |  Building | Period | Grade 

   12345          2         1       11        
   12345          2         5       11
   43210          2         1       12

我想要这个:

Student ID | <u>Building | Period | Grade

12345          2         1,5     11
43210          2         1       12

这是我的疑问:

 select r.STUDENT_ID,
        r.BUILDING ,
        (select ab.attendancePeriod + ','
        from att_bottom ab
        where ab.STUDENT_ID = r.student_id
        and ab.building = '2'
        and ab.attendance_c ='T'
        and ab.SCHOOL_YEAR =2014
        CONVERT(date,ab.attendance_date,102) = convert(date,getdate(),102)  
        FOR XML PATH ('') ) AS PERIODS,
        r.GRADE
        FROM register r
    where r.CURRENT_STATUS = 'A' 
    and r.BUILDING ='2'

我让所有的学生都在2号楼,即使他们没有T的attedance_c;正在检索Periods的NULL值:

Student ID | Building  | Period | Grade 

12345          2        1 , 5    11
43210          2        1  ,     12
95687          2        NULL     09
78417          2        NULL     10
20357          2        NULL     11

我尝试了and ab.attendancePeriod is Not NULL,但我仍然得到了相同的结果。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

将AS PERIODS选择移动为r。

的内连接

答案 1 :(得分:0)

外部查询不会侦听子查询中的任何过滤器;对于任何与连接条件不匹配的行,它将返回NULL。您需要以不同方式过滤。这是一种方法(这也消除了错误的尾随逗号,并避免通过将它们昂贵地转换为字符串来比较日期):

;WITH x AS 
(
  SELECT DISTINCT s = r.Student_ID, r.building,
    p = ab.attendancePeriod, r.grade
  FROM dbo.Register AS r
  INNER JOIN dbo.att_bottom AS ab
  ON r.Student_ID = ab.Student_ID
  AND r.building = ab.building
  WHERE ab.building = '2'
  AND ab.attendance_c = 'T'
  AND ab.SCHOOL_YEAR = 2014
  AND ab.attendance_date >= CONVERT(DATE, GETDATE())
  AND ab.attendance_date < DATEADD(DAY, 1, CONVERT(DATE, GETDATE()))
  AND r.building = '2'
  AND r.CURRENT_STATUS = 'A'
)
SELECT DISTINCT 
  [Student ID] = x.s, 
  x.building,
  Period = STUFF((SELECT ',' + x2.p FROM x AS x2 WHERE x2.s = x.s
    FOR XML PATH(''), TYPE).value('.','nvarchar(max)'),1,1,''), 
  x.grade
 FROM x;

另一种方式:

 SELECT DISTINCT 
   r.Student_ID, 
   r.building, 
   Period = STUFF(b.p.value('.', 'nvarchar(max)'),1,1,''), 
   r.grade
 FROM dbo.Register AS r
 CROSS APPLY 
 (
   SELECT p = ',' + ab.attendancePeriod
     FROM dbo.att_bottom AS ab
     WHERE ab.building = '2' 
     AND ab.attendance_c = 'T'
     AND ab.SCHOOL_YEAR = 2014
     AND ab.attendance_date >= CONVERT(DATE, GETDATE())
     AND ab.attendance_date < DATEADD(DAY, 1, CONVERT(DATE, GETDATE()))
     AND ab.student_id = r.student_id 
     AND ab.building = r.building
     FOR XML PATH(''),TYPE
 ) AS b(p)
 WHERE b.p IS NOT NULL
  AND r.building = '2'
  AND r.CURRENT_STATUS = 'A';