我有一个(相当复杂的)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'无效
为什么不允许这样做?我该怎么做呢?
答案 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));
}