WHERE子句中无效的列名错误,使用CASE选择列

时间:2010-07-16 12:47:24

标签: sql-server tsql case where calculated-columns

我有一个(相当复杂的)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...

我获得了在MS SQL Server Management Studio中执行查询时所期望的所有结果,并列出了我在AS子句中指定的列名。但是,出于某种原因,我不允许在WHERE语句中使用条件值。如果我添加

AND ChannelValue > Limit * p.Percentage / 100

在查询结束时,我在该行上收到错误

  

Msg 207,Level 16,State 1,Line 152
  列名称'ChannelValue'无效

为什么不允许这样做?我该怎么做呢?

4 个答案:

答案 0 :(得分:11)

使用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

答案 1 :(得分:7)

您不能在同一ChannelValue级别的where子句中使用select列名 您必须将整个select放在子查询中。

select ....
from 
( 
your select query
) as innerSelect
where ChannelValue > Limit * p.Percentage / 100

答案 2 :(得分: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 

答案 3 :(得分:-2)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct st *call(void);

int main()
{
struct st *p;
p=call();

printf("enter roll no.\n");
scanf("%d",&p->rollno);

printf("enter name\n");
scanf("%s",&p->name);

printf("enter marks\n");
scanf("%f",&p->marks);

printf("%d %s %f\n",p->rollno,p->name,p->marks);
}

struct st *call(void)
{
return malloc(sizeof(struct st));
}