在WHERE子句中使用别名

5 浏览
0 Comments

在WHERE子句中使用别名

我有一个查询,目的是显示表A中最近没有更新的任何行。(每行应在“month_no”之后的2个月内更新):

SELECT A.identifier
     , A.name
     , TO_NUMBER(DECODE( A.month_no
             , 1, 200803 
             , 2, 200804 
             , 3, 200805 
             , 4, 200806 
             , 5, 200807 
             , 6, 200808 
             , 7, 200809 
             , 8, 200810 
             , 9, 200811 
             , 10, 200812 
             , 11, 200701 
             , 12, 200702
             , NULL)) as MONTH_NO
     , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
  FROM table_a A
     , table_b B
 WHERE A.identifier = B.identifier
   AND TO_NUMBER(DECODE( A.month_no
             , 1, 200803 
             , 2, 200804 
             , 3, 200805 
             , 4, 200806 
             , 5, 200807 
             , 6, 200808 
             , 7, 200809 
             , 8, 200810 
             , 9, 200811 
             , 10, 200812 
             , 11, 200701 
             , 12, 200702
             , NULL)) > TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM'))

WHERE子句中的最后一行导致“ORA-00904 Invalid Identifier”错误。毋庸置疑,我不想在WHERE子句中重复整个DECODE函数。有什么想法?(接受修复和解决方法...)

0
0 Comments

在使用WHERE子句中使用别名时出现的问题是,WHERE子句在查询执行的早期阶段处理,而别名是在查询执行的后期阶段创建的。因此,当我们在WHERE子句中使用别名时,MySQL无法识别该别名。

要解决这个问题,可以使用HAVING子句来代替WHERE子句。在HAVING子句中使用别名是可以的,因为HAVING子句在查询执行的晚期阶段处理,此时别名已经创建。

以下是在使用别名的WHERE子句中遇到问题的代码示例:

SELECT CONCAT(names, surname) AS x FROM clients WHERE x LIKE '%a%'

解决方法是将WHERE子句中的别名替换为原始的列名或表达式。以下是将上述代码示例中的别名替换为原始列名的示例:

SELECT CONCAT(names, surname) AS x FROM clients WHERE CONCAT(names, surname) LIKE '%a%'

通过这种方式,我们可以避免在使用WHERE子句时出现未知列的错误,并正确地使用别名进行查询筛选。

0
0 Comments

使用别名的原因是为了简化查询语句中的列名和表达式,使其更易读和理解。在上述代码中,使用了别名来表示两个计算列:MONTH_NO和UPD_DATE。

然而,代码中存在一个问题:在WHERE子句中使用了别名,即.identifier = B.identifier。这是错误的,因为WHERE子句在数据被检索之前进行过滤,它无法识别别名。

为了解决这个问题,可以使用HAVING子句来过滤别名列。HAVING子句在数据被检索之后进行过滤,可以识别别名。因此,我们可以将WHERE子句中的条件移动到HAVING子句中,即HAVING MONTH_NO > UPD_DATE。

下面是修改后的代码:

SELECT A.identifier
 , A.name
 , TO_NUMBER(DECODE( A.month_no
         , 1, 200803 
         , 2, 200804 
         , 3, 200805 
         , 4, 200806 
         , 5, 200807 
         , 6, 200808 
         , 7, 200809 
         , 8, 200810 
         , 9, 200811 
         , 10, 200812 
         , 11, 200701 
         , 12, 200702
         , NULL)) as MONTH_NO
 , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
FROM table_a A, table_b B
WHERE A.identifier = B.identifier
HAVING MONTH_NO > UPD_DATE

通过将条件移动到HAVING子句中,我们可以正确地使用别名来进行过滤,从而解决了原始代码中的问题。

0
0 Comments

使用WHERE子句中的别名是不可能直接的,因为从时间上看,WHERE发生在SELECT之前,而SELECT总是执行链中的最后一步。解决方法是可以使用子查询进行过滤。某些情况下,这不会对性能产生影响,因为Oracle会在应用外部条件之前将内部查询转化为内部查询,并且只有在成本效益上才会这样做。

0