Выбор псевдонима в случае t-sql - PullRequest
1 голос
/ 16 марта 2012

Я столкнулся с проблемой, которую не знаю, как исправить.В моей хранимой процедуре я использую функцию DATEDIFF (), чтобы вернуть int для разницы дат.В моей логике я также вычел значение из возвращенного значения DATEDIFF (), которое дает мне отрицательное значение.Это сделано специально, так как эта логика предназначена для расчета ставок.

Моя проблема в том, что я использую оператор case, но не могу выбрать столбец, потому что он использует псевдоним.Я хочу написать дополнительную логику, в которой если значение отрицательное, я хочу, чтобы оно отображалось как 0.

См. Мой код ниже для получения дополнительной информации:

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',

Сообщение об ошибкеis:

Неверное имя столбца 'dem_days'.Неверное имя столбца 'det_days'.

Как лучше всего это исправить?

Ответы [ 4 ]

4 голосов
/ 16 марта 2012

используйте эту функцию даты, когда вам нужно.

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',
1 голос
/ 16 марта 2012

Если вы хотите повторно использовать вычисления в вашем SELECT для других столбцов в пределах выбора или в других частях запроса, вам нужно переместить вычисления в подвыбор или CTE. E.g.:

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 после заключительной конечной скобки только потому, что у выбранной таблицы есть для псевдонима.


Если у вас есть расчеты, основанные на вычислениях, основанных на расчетах (и т. Д.), Тогда стиль дополнительного выбора может начать выглядеть немного уродливым / запутанным, поэтому форма CTE может быть предпочтительной:

;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

И, по крайней мере, таким образом, гнездо не выходит из-под контроля.

1 голос
/ 16 марта 2012

Вы не можете использовать псевдоним столбца в предложении 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.

См. " Использование столбца псевдонимов в предложении where в ms-sql 2000 "

0 голосов
/ 16 марта 2012

Это работа для 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...