ソフトウェア開発者の日常

こだわりなく書きたいことを書いていきます。

SQL:SQL Server用UNIONで結果を統合して、ORDER BYでNULLをソート順の下位にする方法

2日続けてのSQLについてです。

 

昨日、ORDER BYにCASE式を導入すれば、NULLをソート順の下位にできると書きました。

SQL:SQL Server用ORDER BYでNULLをソート順の下位にする方法 - ソフトウェア開発者の日常

早速プログラムに反映して、動作確認をしたら、エラーが発生しました。

SQL ServerのManagement Studioで、エラーが発生したSQLを実行すると

ステートメントが UNION、INTERSECT、EXCEPT のいずれかの演算子を含んでいるときは、選択リスト内に ORDER BY 項目が必要です。

 

とエラーメッセージが表示されました。

 

適用したSQLはUNIONを使って、結果を統合しているので、UNIONが原因のようですが、CASE式を止めて単純なORDER BYにすると、エラーにはなりません。

エラーになるSQL

SELECT id, data FROM test WHERE flg = 1
UNION
SELECT id, data FROM test WHERE mode = 2
ORDER BY CASE WHEN seq IS NULL THEN 0 ELSE 1 END DESC, seq

エラーにならないSQL

SELECT id, data FROM test WHERE flg = 1
UNION
SELECT id, data FROM test WHERE mode = 2
ORDER BY seq

 

UNIONを使ったときに、CASE式は使えないようだということはわかりましたが、対処の方法がエラーメッセージからは思いつきません。

対処方法を調べた結果、

SELECT * FROM (
    SELECT id, data FROM test WHERE flg = 1
    UNION
    SELECT id, data FROM test WHERE mode = 2
) AS SELECTSET
ORDER BY CASE WHEN seq IS NULL THEN 0 ELSE 1 END DESC, seq

未ソートで統合した結果をサブクエリとして、ソート条件だけ改めて指定する方法になりました。

 

サブクエリは、上手くいったときに改めて便利さを感じます。