Ссылка на созданный столбец в том же операторе выбора - PullRequest
0 голосов
/ 10 июля 2020

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

Можно ли ссылаться на созданные столбцы в том же предложении select, where или having? В каких местах на него можно ссылаться, а где нельзя? Спасибо за любые разъяснения.

select p.fname, p.lname,
case when p.fname = 'dude'
  then 'cool'
  else 'not cool'
end as is_cool
from person p
on p.age > 20
and is_cool = 'cool'

или

select e.startdate, e.enddate,
case when e.startdate > e.enddate
  then format(dateadd(day, 1, e.enddate), 'M/d/yyyy')
  else format(dateadd(day, 5, e.enddate), 'M/d/yyyy')
end as newdate
case when 'newdate' > e.enddate
  then 'too many'
  else 'not enough'
end as dates
from event e

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Для того, чтобы код был немного более лаконичным, перекрестное применение может быть полезно для такого рода вещей. Вы перекрестно применяете выражение или несколько выражений, на которые затем можете ссылаться по имени, без необходимости повторять весь список столбцов, изменять псевдонимы и т. Д. Особенно, если у вас несколько уровней вложенности. Это сложно описать словами, вот пример:

select   v.a,
         v.b,
         v.c,
         v.d,
         v.a_plus_b,
         v.a_times_b,         
         v.a_plus_b_squared
from     (
            select u.a,
                   u.b,       
                   u.c,
                   u.d,  
                   u.a_times_b,    
                   u.a_plus_b,
                   a_plus_b_squared = u.a_plus_b * u.a_plus_b
            from   (
                      select t.a,
                             t.b,
                             t.c,
                             t.d,
                             a_times_b = t.a * t.b,
                             a_plus_b = t.a + t.b
                      from   t
                   ) u
 
         ) v
where    v.a_plus_b_squared > 100
order by v.a_times_b

Это невероятно многословно по сравнению с этим:

select      t.a,
            t.b,
            t.c,
            t.d,
            u.a_plus_b,
            u.a_times_b,
            v.a_plus_b_squared
from        t
cross apply (select t.a * t.b, t.a + t.b)    u (a_times_b, a_plus_b)
cross apply (select u.a_plus_b * u.a_plus_b) v (a_plus_b_squared)
where       v.a_plus_b_squared > 100
order by    u.a_times_b
0 голосов
/ 10 июля 2020

Вы можете ссылаться только на вычисляемый столбец в предложении order by. Для любого другого использования либо используйте подзапрос, либо повторите лог c.

Подзапрос:

select PO.fname, PO.lname, PO.is_cool
from (
  select PI.fname, PI.lname, PI.age
    case when PI.fname = 'dude'
      then 'cool'
      else 'not cool'
    end as is_cool
  from dbo.person PI
) PO
where PO.age > 20
and PO.is_cool = 'cool';

Повторный лог c:

select p.fname, p.lname, 
  case when p.fname = 'dude'
    then 'cool'
    else 'not cool'
  end as is_cool
from dbo.person p
where p.age > 20
-- Same logic as to get 'cool'
and p.fname = 'dude';

Order by возможно:

select p.fname, p.lname, 
  case when p.fname = 'dude'
    then 'cool'
    else 'not cool'
  end as is_cool
from dbo.person p
where p.age > 20
order by is_cool;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...