20

一个sql脚本,在生产服务器上运行了很长时间没有问题,但是最近系统报告“如果语句包含UNION运算符,ORDER BY项目必须出现在选择列表中”

奇怪的是 sql 脚本仍然可以在我的测试服务器上运行。所以我不知道我所做的任何修订是否可以在生产中正确运行。

SELECT '' as value ,'Outstanding' as text , 0 as disp_order
union
select a.buyer_status_code AS value , a.buyer_status_name AS text ,a.disp_order
FROM   rfq_buyer_status_v a WITH (NOLOCK)
ORDER BY a.disp_order
4

2 回答 2

37

尝试这个:

select * from 
(
SELECT '' as value ,'Outstanding' as text , 0 as disp_order
union
select a.buyer_status_code AS value , a.buyer_status_name AS text ,a.disp_order
FROM   rfq_buyer_status_v a WITH (NOLOCK)
) t

ORDER BY t.disp_order
于 2012-11-22T09:38:42.623 回答
29

SQL Server 按阶段顺序解析查询,如下所示:

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

每个阶段对一个或多个表作为输入进行操作,并返回一个虚拟表作为输出。一个阶段的输出表被认为是下一阶段的输入。这与产生关系的关系上的操作是一致的。如果指定了 ORDER BY,则结果不是关系的。

在较早阶段定义的任何别名都可以被其后的阶段看到,但反之则不然。

例如

以下查询没问题

SELECT [Col_1], [Col_2] 
FROM Table_A AS A 
WHERE A.[Col_1] > 0
ORDER BY A.[Col_2]; 

虽然这个不行

SELECT [Col_1] AS C1, [Col_2] AS C2 
FROM Table_A 
WHERE C1 > 0
ORDER BY C2; 

现在,UNION 集合运算符统一了两个输入查询的结果。作为集合运算符,UNION 具有隐含的 DISTINCT 属性,这意味着它不会返回重复的行。

如果您在查询中使用了 UNION,它将两个集合合并为一个,并且 ORDER BY 将对组合集合生效,而不仅仅是 SELECT ... FROM ... 数据集。原因是 ORDER BY 是队列中最弱的(或最后一个),它“抓住所有”

在查询的第一行中,您为 0 提供了一个名为“disp_order”的别名,这很好。在 UNION 运算符之后,您从表“rfq_buyer_status_v”中查询了一个数据集,其中包含一个名为“disp_order”的列,这也是完全可以接受的。问题出现在 ORDER BY 之后。

由于您还为表指定了别名,即“a”,因此 ORDER BY a.disp_order 意味着限制对部分组合数据集的排序操作,这与“Catches All”活动相冲突。

解决方案是删除“a”。在 ORDER BY 子句之后。你可以这样做的原因是你给了 0 别名'disp_order',它与表 rfq_buyer_status_v 中的列名相同。那么在这种情况下,我看不到任何别名表的价值......

SELECT '' AS value ,'Outstanding' AS text , 0 AS disp_order
UNION 
SELECT a.buyer_status_code AS value , a.buyer_status_name AS text ,a.disp_order
FROM   rfq_buyer_status_v a WITH (NOLOCK)
ORDER BY disp_order

编写查询的另一种方法是

SELECT ''            AS value ,
       'Outstanding' AS text  , 
       0             AS ABC
UNION 
SELECT buyer_status_code AS value , 
       buyer_status_name AS text ,
       disp_order        AS ABC
FROM   rfq_buyer_status_v 
    WITH (NOLOCK)
ORDER BY ABC

第二个为 disp_order 列提供了一个完全不同的别名,使其易于阅读,并减少了在查看代码时感到困惑的机会。

于 2013-10-16T06:11:12.253 回答