SQL-2带UNION和with的SELECT语句

SQL-2带UNION和with的SELECT语句,sql,sql-server,Sql,Sql Server,我有一个WITH语句,我想对结果进行一些计算,这就是为什么我使用WITH和SELECT 假设SELECT语句收集了20名成绩最好的学生 现在我想得到20名成绩最差的学生,所以我尝试了另一个 WITH cteGrades AS ( SELECT * FROM tbl_students ) --Selecting best Grade SELECT TOP(20) cte.name, cte.surname, cte.grade FROM cteGrade c

我有一个WITH语句,我想对结果进行一些计算,这就是为什么我使用WITH和SELECT

假设SELECT语句收集了20名成绩最好的学生

现在我想得到20名成绩最差的学生,所以我尝试了另一个

WITH cteGrades AS 
( 
    SELECT *
    FROM tbl_students
)
--Selecting best Grade 
SELECT TOP(20)
    cte.name, cte.surname, cte.grade
FROM 
    cteGrade cte
ORDER BY 
    cte.grade DESC

UNION

--Selecting worst Grade 
SELECT TOP(20)
    cte.name, cte.surname, cte.grade
FROM 
    cteGrades cte
ORDER BY 
    cte.grade ASC
我得到一个错误:

关键字“UNION”附近的语法不正确

您应该删除union子句中的order by。对整个结果集执行并集后的排序。或者将查询作为CTE并对结果执行并集

 WITH cteGrade AS 
          ( 
            SELECT  *
            FROM tbl_students
           )
            --Selecting best Grade 
 , top20 as 
            (SELECT TOP(20)
                 cte.name
                ,cte.surname
                ,cte.grade
            FROM cteGrade cte
            ORDER BY cte.grade DESC)
 , last20 as 
             (
            --Selecting worst Grade 
            SELECT TOP(20)
                 cte.name
                ,cte.surname
                ,cte.grade
            FROM cteGrade cte
            ORDER BY cte.grade ASC
             )
 select name, surname, grade from top20
 union all
 select name, surname, grade from last20

原始查询只是缺少子查询周围的括号:

WITH cteGrades AS ( 
      SELECT *
      FROM tbl_students
     )
--Selecting best Grade 
(SELECT TOP(20) cte.name, cte.surname, cte.grade
 FROM cteGrade cte
 ORDER BY cte.grade DESC
) UNION
(SELECT TOP(20) cte.name, cte.surname, cte.grade
 FROM cteGrades cte
 ORDER BY cte.grade ASC
);
重写以使用CTE或行号也是可能的,但实际上没有理由这样做

事实上,您根本不需要CTE:

(SELECT TOP(20) s.name, s.surname, s.grade
 FROM tbl_students s
 ORDER BY s.grade DESC
) UNION
(SELECT TOP(20) s.name, s.surname, s.grade
 FROM tbl_students s
 ORDER BY s.grade ASC
);

去除在描述之后,如果您的CTE没有对数据进行过滤/计算/连接/任何操作,那么使用CTE是没有意义的..cteGrade vs cteGrades-我认为您的命名是错误的…您不能在联合之前排序。@rwking correct-但令人困惑的是,如果使用TOP运算符,您可以在子查询内部排序。这就是为什么我更喜欢M.Ali的应答窗口功能,因为它不需要TOP。它们当然是:和?您想要的项目同时在20个最佳和20个最差中?应该是在WHERE子句中还是在WHERE子句中@达米恩?不信的人打败了我
(SELECT TOP(20) s.name, s.surname, s.grade
 FROM tbl_students s
 ORDER BY s.grade DESC
) UNION
(SELECT TOP(20) s.name, s.surname, s.grade
 FROM tbl_students s
 ORDER BY s.grade ASC
);