CASE
単一の値を生成する式です。他の言語で行ったり、 で試したりするようなフローの制御には使用できませんIF
。IF
クエリ内でも使用できません。
以下では、各条件を個別に扱います。条件が一致しない場合、その式の結果は NULL になり、どの順序でも無視されます。したがって、すべての条件が真である句のみが観察されるため、これらの句の順序は関係ありません。
ORDER BY
CASE WHEN @SortColumn = 'Type' AND @SortDir = 'DESC' THEN Type END DESC,
CASE WHEN @SortColumn = 'Name' AND @SortDir = 'DESC' THEN Name END DESC,
CASE WHEN @SortColumn = 'Type' AND @SortDir = 'ASC' THEN Type END,
CASE WHEN @SortColumn = 'Name' AND @SortDir = 'ASC' THEN Name END;
これらはおそらくある程度組み合わせることができますが、データ型がわからないので、これがおそらく最も安全です。データ型が同じ場合は、次のようになります。
ORDER BY
CASE WHEN @SortDir = 'DESC' THEN
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END
END DESC,
CASE WHEN @SortDir = 'ASC' THEN
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END
END;
ASC
条件付き対DESC
1 つの式で実行できないため、これ以上折りたたむことはできません。ただし、他の方法で単純化することもできます。たとえば、次のクエリは上記と同じ結果をもたらしますが、場合によっては order by が実行しようとします (たとえば) ORDER BY Type DESC, Type DESC
- オプティマイザーがそれを冗長として単純化するかどうかは 100% わかりませんただし、単一の並べ替え演算子に折りたたむ必要があります (必要な場合 - このクエリは、クエリを満たすために使用されるインデックスに基づいて固有の並べ替えを生成する場合があります)。
ORDER BY
CASE WHEN @SortColumn = 'Type' AND @SortDir = 'DESC' THEN Type END DESC,
CASE WHEN @SortColumn = 'Name' AND @SortDir = 'DESC' THEN Name END DESC,
CASE WHEN @SortColumn = 'Type' THEN Type END,
CASE WHEN @SortColumn = 'Name' THEN Name END;
...また...
ORDER BY
CASE WHEN @SortDir = 'DESC' THEN
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END
END DESC,
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END;
動的 SQL を検討することもできます。これがさらに複雑になると、ここで多くのメンテナンスが必要になるからです。
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT ... ORDER BY ' + @SortColumn + ' ' + @SortDir;
PRINT @sql;
-- EXEC sp_executesql @sql;
もちろん、これにより他の問題が発生する可能性があります (残りのクエリの保守性、プラン キャッシュの肥大化など)。