Issue with Order By with FOR XML in T-sql(ORDER BY 子句在视图、内联函数、派生表中无效)

Issue with Order By with FOR XML in T-sql (The ORDER BY clause is invalid in views, inline functions, derived tables)

select a.Hall, a.Title, 
  STUFF((SELECT ', ' + '[' + CONVERT(varchar(2),DATEPART(Hour, b.StartFilm))  
  + ':' + CONVERT(varchar(2),DATEPART(Minute, b.StartFilm)) 
  + ' ' + CONVERT(varchar(2),DATEPART(Hour, b.EndTime))  
  + ':' + CONVERT(varchar(2),DATEPART(Minute, b.EndTime)) 
  + ']' 
FROM (select c.Name as Hall, b.Title, 
    Convert(time,a.StartFilmTime) as StartFilm,  
    Convert(time,a.EndFilmTime) as EndTime
  from FilmSchedule a 
    left join Film b on a.FilmId = b.Id 
    left join Room c on a.RoomId = c.Id 
  where a.ApproveStatus = 1 and a.Status = 1 
        and CONVERT(date, a.StartFilmTime) =  '05-06-2015'
) b 
Where a.Hall = b.Hall and a.Title = b.Title 
FOR XML PATH('')),1,1,'') As ShowTime  
from (select c.Name as Hall, b.Title, 
  Convert(time,a.StartFilmTime) as StartFilm,  
  Convert(time,a.EndFilmTime) as EndTime
  from FilmSchedule a 
  left join Film b on a.FilmId = b.Id 
  left join Room c on a.RoomId = c.Id 
  where a.ApproveStatus = 1 and a.Status = 1 
     and CONVERT(date, a.StartFilmTime) =  '05-06-2015'
  Order by a.StartFilmTime
) a 
group by a.Hall, a.Title

我收到错误:

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.

请帮忙! (我用过FOR XML?)

尽管您的查询确实使用了 FOR XML(对于 GROUP_CONCAT workaround),但您是在使用 FOR XML 的派生 table 之外应用顺序,因此错误。

鉴于您没有在最后的 select 中直接包含开始日期(尽管您将其作为 STUFF ShowTime 列的一部分),您也不能 ORDER BY StartFilm 在最后的 GROUP BY 中,否则该列将需要包含在 GROUP BY 中或作为聚合列。

你可以做的是将 ORDER BY 移到 STUFF 中,然后按派生列 ShowTime 排序(因为你的查询只运行给定的一天,而 StartFilmTime 是的第一部分STUFFED 组成的列)。

同时,我会用 CTE 干掉派生 table 上的重复:

WITH cteFiltered AS
    (select c.Name as Hall, b.Title, 
        Convert(time,a.StartFilmTime) as StartFilm,  
        Convert(time,a.EndFilmTime) as EndTime
    from FilmSchedule a 
        left join Film b on a.FilmId = b.Id 
        left join Room c on a.RoomId = c.Id 
    where a.ApproveStatus = 1 and a.Status = 1 
          and CONVERT(date, a.StartFilmTime) =  '05-06-2015'
    )
select 
    a.Hall, 
    a.Title, 
    STUFF((SELECT ', ' + '[' + CONVERT(varchar(2),DATEPART(Hour, b.StartFilm))  
    + ':' + CONVERT(varchar(2),DATEPART(Minute, b.StartFilm)) 
    + ' ' + CONVERT(varchar(2),DATEPART(Hour, b.EndTime))  
    + ':' + CONVERT(varchar(2),DATEPART(Minute, b.EndTime)) 
    + ']' 
        FROM
            cteFiltered b
        Where 
            a.Hall = b.Hall and a.Title = b.Title 
        order by b.StartFilm -- ***
        FOR XML PATH('')),1,1,'') As ShowTime  
from 
    cteFiltered a 
group by a.Hall, a.Title
order by ShowTime; -- *** Hour is first (assuming 24H format) and only one day