web-dev-qa-db-ja.com

SQL ServerのCASE WHEN内で複数の列を選択するにはどうすればよいですか?

このサイトを広範囲に検索しましたが、解決策が見つかりません。

これが私のクエリの例です:

SELECT 
   ActivityID,

   Hours = (CASE 
                WHEN ActivityTypeID <> 2 THEN
                     FieldName = (Some Aggregate Sub Query),
                     FieldName2 = (Some other aggregate sub query)
                WHEN ActivityTypeID = 2 THEN
                     FieldName = (Some Aggregate Sub Query with diff result),
                     FieldName2 = (Some Other Aggregate Sub Query with diff result)
           END)

明らかにクエリの多くを省いていますが、それが可能かどうかを見たかっただけです。

私はおそらく「CASE」を2回行うことができると思いますが、尋ねると思いました...

24
Joshua

いいえ、CASEは関数であり、単一の値のみを返すことができます。 CASEロジックを複製する必要があると思います。

もう1つのオプションは、クエリ全体をIFでラップし、結果を返す2つの別個のクエリを使用することです。クエリの残りの部分を見ることなく、それがあなたのために働くかどうかを言うのは難しいです。

13
Pete McKinney

「ケース」は単一の値のみを返すことができますが、複合型を使用できます。

create type foo as (a int, b text);
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*;
1
Ghost

実際にそれを行うことができます。

しかし、誰かがCASEステートメントを繰り返すことは見た目ほど悪くないことに注意すべきです。 SQL Serverのクエリオプティマイザーは、CASEを2回実行しないほど賢く、そのためにパフォーマンスが低下することはありません。

さらに、誰かが次のロジックを使用して、CASEを繰り返さない場合があります(自分に合っている場合)。

INSERT INTO dbo.T1
(
    Col1,
    Col2,
    Col3
)
SELECT
    1,
    SUBSTRING(MyCase.MergedColumns, 0, CHARINDEX('%', MyCase.MergedColumns)),
    SUBSTRING(MyCase.MergedColumns, CHARINDEX('%', MyCase.MergedColumns) + 1, LEN(MyCase.MergedColumns) - CHARINDEX('%', MyCase.MergedColumns))
FROM
    dbo.T1 t
LEFT OUTER JOIN
(
    SELECT CASE WHEN 1 = 1 THEN '2%3' END MergedColumns
) AS MyCase ON 1 = 1

これにより、テーブルT1の各レコードに値(1、2、3)が挿入されます。これは、区切り文字'%'を使用して、マージされた列を分割します。ニーズに応じて独自の分割関数を作成できます(たとえば、nullレコードの処理や、varcharフィールドなどの複雑な区切り文字の使用)。ただし、主なロジックは、CASEステートメントを結合し、分割ロジックを使用して結合の結果セットから選択することです。

0
sotn