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 列にまったく別のエイリアスを付けて読みやすくし、コードを確認するときに混乱する可能性を減らしました。