9

多くの異なるテーブルからデータを選択する(かなり複雑な)SQLステートメントがあり、古いレガシーデータ構造に対処するために、他の列の値に基づいて値を取得するカスタム列がいくつかあります。私は現在、CASEステートメントでこれを解決しました:

 SELECT
     ...,
     CASE channel
         WHEN 1 THEN channel_1
         WHEN 2 THEN channel_2
         ...
         ELSE 0
     END AS ChannelValue,
     CASE channelu
         WHEN 1 THEN channelu_1
         WHEN 2 THEN channelu_2
         ...
         ELSE '0'
     END AS ChannelWithUnit,
     ...
 FROM 
     ... 
 --rest of statement continues with multiple joins and where/and clauses...

ASMS SQL Server Management Studioでクエリを実行すると期待するすべての結果が得られ、句で指定したとおりに列名が一覧表示されます。ただし、何らかの理由で、WHEREステートメントで条件値を使用することは許可されていません。追加した場合

AND ChannelValue > Limit * p.Percentage / 100

クエリの最後に、その行に次のようなエラーが表示されます

メッセージ207、レベル16、状態1、行152
無効な列名'ChannelValue'

なぜこれが許可されないのですか?代わりに何をすべきですか?

4

4 に答える 4

12

SELECTリストで宣言されたエイリアスを使用することが有効であるSQLステートメントの唯一の部分はORDER BY句です。クエリの他の部分については、CASE式全体を繰り返し、オプティマイザーが同じであることを認識できるようにする必要があります。

SQL2005 +を使用している場合は、CTEを使用してこの問題を回避できます。これは、読みやすさに役立つ場合があります。

WITH YourQuery As
(

 SELECT
     Limit, 
     Percentage,
     CASE channel
         WHEN 1 THEN channel_1
         WHEN 2 THEN channel_2
         ...
         ELSE 0
     END AS ChannelValue,
     CASE channelu
         WHEN 1 THEN channelu_1
         WHEN 2 THEN channelu_2
         ...
         ELSE '0'
     END AS ChannelWithUnit,
     ...
 FROM 
)

select ...
FROM YourQuery WHERE
ChannelValue > Limit * Percentage / 100
于 2010-07-16T12:53:54.050 に答える
7

同じレベルChannelValueのwhere句で列名を使用することはできません。 この全体をサブクエリに入れる必要があります。select
select

select ....
from 
( 
your select query
) as innerSelect
where ChannelValue > Limit * p.Percentage / 100
于 2010-07-16T12:50:49.517 に答える
2

あなたはCTEを使うことができます-のようなもの

WITH CTE AS
(
SELECT 
     ..., 
     CASE channel 
         WHEN 1 THEN channel_1 
         WHEN 2 THEN channel_2 
         ... 
         ELSE 0 
     END AS ChannelValue, 
     CASE channelu 
         WHEN 1 THEN channelu_1 
         WHEN 2 THEN channelu_2 
         ... 
         ELSE '0' 
     END AS ChannelWithUnit, 
     ... 
 FROM  
)
SELECT * 
FROM CTE
WHERE ChannelValue > Limit * p.Percentage / 100 
于 2010-07-16T12:54:35.750 に答える
-2
-- SOMETHING FROM ADVENTURE WORKS THIS WORKS AS THE ABOVE POSTER
--- USING 'WITH CTE AS'
-- MY ANSWER TO A QUERY

WITH CTE AS
 (
 SELECT HE.Gender AS [GENDER], HE.HireDate AS [HIREDATE],      HE.BirthDate AS [BIRTHDATE],
CASE
WHEN DATEPART(YY,[BIRTHDATE]) BETWEEN 1962 AND 1970 AND [GENDER] = 'M' AND DATEPART(YY,[HIREDATE]) > 2001  THEN 'MALE'
WHEN DATEPART(YY,[BIRTHDATE]) BETWEEN 1972 AND 1975 AND [GENDER] = 'F' AND DATEPART(YY,[HIREDATE]) BETWEEN 2001 AND 2002 THEN 'FEMALE'
ELSE 'NOTREQUIRED'
END AS [RESULT]
FROM [HumanResources].[Employee] AS HE
)
SELECT *
FROM CTE
WHERE [RESULT] <> 'NOTREQUIRED' -- GOT THIS TOO WORK NO FEMALES IN RESULT
ORDER BY [RESULT]
于 2017-04-13T18:46:15.143 に答える