2012-03-16 9 views
1

私は修正方法がわからない問題が出てきました。私のストアドプロシージャでは、DATEDIFF()関数を使用して日付差のintを返します。私のロジックでは、負の値を与えているDATEDIFF()の戻り値から値を減算しています。これは、このロジックがレートを調整するためのものであるため、設計によるものです。t-sqlの場合にエイリアスを選択する

私の問題は、ケースステートメントを使用していますが、エイリアスを使用しているため、列を選択できません。

DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 AS dem_days, -- Date difference to work out Demurrage days 
DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, GETUTCDATE())) - 21 AS det_days, 

CASE WHEN dem_days <= 0 THEN 0 END AS 'test1', 
CASE WHEN det_days <= 0 THEN 0 END AS 'test2', 

エラーメッセージは次のとおりです:私は何を目指すことは値が負の場合、私はより多くの情報については、以下の私のコードを参照してください。それが0

として表示するいくつかの追加のロジックを記述することです

無効な列名 'dem_days'です。 無効な列名 'det_days'です。

これを解決する最適な解決策は何ですか?

答えて

4

必要なときにいつでもこの機能を使用してください。

DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 AS dem_days, -- Date difference to work out Demurrage days 
DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, GETUTCDATE())) - 21 AS det_days, 

CASE WHEN DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 <= 0 THEN 0 END AS 'test1', 
CASE WHEN DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, GETUTCDATE())) - 21 <= 0 THEN 0 END AS 'test2', 
+0

これは完全に機能しました。私はゼロよりも小さくない場合に値を評価しないelse条件を追加しました。ゼロまたはゼロより大きい数値が表示されますが、同時にレートがそのまま維持されます。ありがとうございます!! –

1

WHERE句には、列エイリアスを使用できません。あなたのSELECTからのステートメントを繰り返す必要があります:

SELECT 
DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 AS dem_days, -- Date difference to work out Demurrage days 
DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, GETUTCDATE())) - 21 AS det_days 
FROM Table 
WHERE 
CASE WHEN DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 <= 0 THEN 0 END AS 'test1', 
CASE WHEN DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, GETUTCDATE())) - 21 <= 0 THEN 0 END AS 'test2' 

エイリアス名でWHERE句を使用する必要がある場合は、あなたがこのようなあなたのクエリを構築することができます

select * 
from 
    (
    select a + b as aliased_column 
    from table 
    ) dt 
where dt.aliased_column = something. 

"Using an Alias column in the where clause in ms-sql 2000"

+0

'HAVING'ビットは疑わしいと思われます。式は値を返しますが、' HAVING'節は述語だけを評価します。 –

+0

@Damien_The_Unbeliever良い点、私は答えから削除しました – Curt

1

SELECTの計算を、選択内の他の列またはクエリの他の部分に再利用したい場合は、m副選択またはCTEに計算を反映させる。例えば:

SELECT 
    --Useful columns for final result (e.g. other columns from your original query) 
    CASE WHEN dem_days <= 0 THEN 0 END AS 'test1', 
    CASE WHEN det_days <= 0 THEN 0 END AS 'test2' 
FROM 
(
    SELECT 
     --Other columns (not shown in OPs question) 
      DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 AS dem_days, -- Date difference to work out Demurrage days 
      DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, GETUTCDATE())) - 21 AS det_days 
    FROM 
     --Original Query 
) t 

tサブ選択テーブルエイリアスを有することを有しているという理由だけで、最終的なエンドブラケットされた後。

;With FirstCalcs as (
    SELECT BaseColumn1,BaseColumn2,CalculatedColumn1,CalculatedColumn2 
    FROM .... 
), SecondCalcs as (
    SELECT BaseColumn1,BaseColumn2,CalculatedColumn1,CalculatedColumn3 --3 depends on 1 & 2 
    FROM FirstCalcs 
), ThirdCalcs as (
    SELECT BaseColumn1,BaseColumn2,CalculatedColumn1 
    FROM SecondCalcs 
    WHERE CalculatedColumn3 = <Condition> 
) 
SELECT <Final result columns> 
FROM ThirdCalcs 


あなたは(など)の計算に基づいた計算に基づいて計算を持っている場合は、サブ選択スタイルは少し、紛らわしい/醜いCTEフォームが好まれるかもしれないので、を見て開始することができます

少なくともそのように、入れ子は手を出さない。

0

これはCROSS APPLYの仕事です。

SELECT D.dem_days 
    , D.det_days 
    , T.test1 
    , T.test2 
FROM cncr 
CROSS APPLY (SELECT 
    dem_days = DATEDIFF(d, cncr.vso.pod_ata, ISNULL(cncr.cntr_date3, 
       GETUTCDATE())) - 14 
    , det_days = DATEDIFF(d, cncr.dc_ata, ISNULL(cncr.empty_return_dt, 
       GETUTCDATE())) - 21 
) D 
CROSS APPLY (SELECT 
    test1 = CASE WHEN D.dem_days <= 0 THEN 0 END 
    , test2 = CASE WHEN D.det_days <= 0 THEN 0 END 
) T 
関連する問題