首页 > 解决方案 > 在同一个 select 语句中引用创建的列

问题描述

我在尝试引用之前在同一选择中创建的内部列时得到不一致的结果。

可以在同一个select, where, orhaving子句中引用创建的列吗?哪些地方可以引用,哪些不能引用?感谢您的任何澄清。

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

标签: sqlsql-server

解决方案


为了使代码更简洁一点,交叉应用对这种事情很有用。您可以交叉应用一个表达式或多个表达式,然后您可以按名称引用它们,而无需重复整个列列表、更改别名等。特别是当您有多个嵌套级别时。这很难用语言来描述,这里有一个例子:

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

推荐阅读