列が存在する場合は列の値を選択でき、それ以外の場合はnullを選択できるかどうか疑問に思っています。つまり、列が存在しない場合を処理するために、selectステートメントを「リフト」したいのです。
SELECT uniqueId
, columnTwo
, /*WHEN columnThree exists THEN columnThree ELSE NULL END*/ AS columnThree
FROM (subQuery) s
注意してください、私は自分のデータモデルと設計を固めることに取り組んでいます。今後数週間でこのロジックを除外したいと思っていますが、データモデルの修正は今取り組むよりも時間がかかるため、この問題を乗り越えたいと思います。
また、これを1つのクエリで実行できるようにしたいと思います。だから私はのような答えを探していません
最初にサブクエリの列を確認してください。次に、クエリを変更して、サブクエリの列を適切に処理します。
簡単なSQLステートメントでこれを行うことはできません。テーブル内のすべてのテーブルおよび列参照が存在しない限り、SQLクエリはコンパイルされません。
「サブクエリ」がテーブル参照またはビューの場合、ダイナミックSQLでこれを実行できます。
動的SQLでは、次のようなことを行います。
_declare @sql nvarchar(max) = '
SELECT uniqueId, columnTwo, '+
(case when exists (select *
from INFORMATION_SCHEMA.COLUMNS
where tablename = @TableName and
columnname = 'ColumnThree' -- and schema name too, if you like
)
then 'ColumnThree'
else 'NULL as ColumnThree'
end) + '
FROM (select * from '+@SourceName+' s
';
exec sp_executesql @sql;
_
実際のサブクエリの場合、サブクエリがその列名で何かを返すかどうかを確認することで、同じことを近似できます。そのための1つの方法は、クエリselect top 0 * into #temp from (<subquery>) s
を実行し、_#temp
_の列をチェックすることです。
他の人がすでに提案したように、正気なアプローチは、テーブルの設計を満たすクエリを持つことです。
ただし、(動的ではなく、純粋な)SQLで必要なことを実現するための、かなりエキゾチックなアプローチがあります。同様の問題がDBA.SEに投稿されました: 列が存在する場合に特定の行を選択する方法、または列が存在しない場合にすべての行を選択する方法 。あなたの問題はより複雑なので、クエリは控えめに言ってもより複雑です。ここに、非常識なアプローチがあります:
; WITH s AS
(subquery) -- subquery
SELECT uniqueId
, columnTwo
, columnThree =
( SELECT ( SELECT columnThree
FROM s AS s2
WHERE s2.uniqueId = s.uniqueId
) AS columnThree
FROM (SELECT NULL AS columnThree) AS dummy
)
FROM s ;
また、uniqueId
がサブクエリの結果セットで一意であると想定しています。
SQL-Fiddleでテスト済み
そして、単一のサブクエリで複数の列を許可する追加の利点がある、より単純なメソッド:
SELECT s.*
FROM
( SELECT NULL AS columnTwo,
NULL AS columnThree,
NULL AS columnFour
) AS dummy
CROSS APPLY
( SELECT
uniqueId,
columnTwo,
columnThree,
columnFour
FROM tableX
) AS s ;
質問はDBA.SEでも尋ねられ、 @ Andriy M (CROSS APPLY
も使用!)および Michael Ericsson (XML
を使用)で回答されました。
CASEステートメントを使用して、列が存在するかどうかを確認し、そこからSELECTできないのはなぜですか?