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 サーバーは、次のフェーズの順序でクエリを解析します。

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

各フェーズは、1 つ以上のテーブルを入力として操作し、仮想テーブルを出力として返します。1 つのフェーズの出力テーブルは、次のフェーズへの入力と見なされます。これは、関係を生成する関係に対する操作と一致しています。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 セット演算子は 2 つの入力クエリの結果を統合しています。セット演算子として、UNION には暗黙の DISTINCT プロパティがあります。つまり、重複する行は返されません。

クエリで UNION を使用すると、2 つのセットが 1 つに結合され、ORDER BY は SELECT ... FROM ... データセットだけでなく、結合されたセットに対して有効になります。その理由は、ORDER BY がキューの中で最も弱い (または最後のもの) であり、「すべてをキャッチする」ためです。

クエリの最初の行で、0 に「disp_order」というエイリアスを指定しましたが、これで問題ありません。UNION 演算子の後で、「disp_order」という名前の列を含むテーブル「rfq_buyer_status_v」からデータセットをクエリしましたが、これもまったく問題ありません。問題はORDER BYの後から出てきます。

テーブルにエイリアス、つまり「a」も指定したため、ORDER BY a.disp_order は結合されたデータセットの部分的な順序付けアクションを制限することを意味し、「すべてをキャッチ」アクティビティと競合します。

解決策は、「a.」を削除することです。ORDER BY 句の後。このようにできる理由は、テーブル rfq_buyer_status_v の列名と同じエイリアス「disp_order」を 0 に指定したためです。この場合、テーブルのエイリアシングの値を確認できませんでした...

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

2 つ目は、disp_order 列にまったく別のエイリアスを付けて読みやすくし、コードを確認するときに混乱する可能性を減らしました。

于 2013-10-16T06:11:12.253 に答える