Sql 在WHERE子句中使用别名
我有一个查询,用于显示表a中最近没有更新的任何行。每行应在月号之后的2个月内更新:Sql 在WHERE子句中使用别名,sql,oracle,alias,decode,ora-00904,Sql,Oracle,Alias,Decode,Ora 00904,我有一个查询,用于显示表a中最近没有更新的任何行。每行应在月号之后的2个月内更新: SELECT A.identifier , A.name , TO_NUMBER(DECODE( A.month_no , 1, 200803 , 2, 200804 , 3, 200805 , 4, 200806 , 5, 200807
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 MONTH_NO > UPD_DATE
WHERE子句中的最后一行导致ORA-00904无效标识符错误。不用说,我不想在WHERE子句中重复整个DECODE函数。有什么想法吗?修复和解决方案都被接受…这不可能直接实现,因为按时间顺序,在选择之前发生,选择始终是执行链中的最后一步 您可以对其进行子选择和筛选:
SELECT * FROM
(
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
) AS inner_table
WHERE
MONTH_NO > UPD_DATE
从评论中向上移动了一些有趣的信息:
不应该有性能上的打击。
Oracle不需要具体化
应用外部查询之前的内部查询
Oracle将考虑的条件
在内部和外部转换此查询
将谓词向下推到内部
查询,如果是成本,则会这样做
有效
或者,您可以在HAVING子句中使用别名,就像您可以使用的另一种方法一样:
WITH inner_table AS
(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)
SELECT * FROM inner_table
WHERE MONTH_NO > UPD_DATE
您还可以为队列创建一个永久视图,并从视图中选择
CREATE OR REPLACE VIEW_1 AS (SELECT ...);
SELECT * FROM VIEW_1;
可以有效地定义一个变量,该变量可以在SELECT、WHERE和其他子句中使用 子查询不一定允许对引用的表列进行适当的绑定,但是外部应用允许
SELECT A.identifier
, A.name
, vars.MONTH_NO
, TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
FROM table_a A
, table_b B ON A.identifier = B.identifier
OUTER APPLY (
SELECT
-- variables
MONTH_NO = 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))
) vars
WHERE vars.MONTH_NO > UPD_DATE
值得称赞。这将是一个有趣的方法,你能给出任何代码吗?适用于何处的规则相同,因此这不是一个解决方案。我被MySQL 5.5卡住了,不知道这是否适用于Oracle。但是:从具有类似于“%a%”的x的客户机中选择CONCATnames,姓氏为x有效,而从具有类似于“%a%”的x失败的客户机中选择CONCATnames,姓氏为x,其中“WHERE子句”中的未知列“x”是真正的答案。HAVING是SELECT查询中计算列(如COUNT、MAX和其他表达式)的子句检查器,因为它过滤最终获取的数据。
SELECT A.identifier
, A.name
, vars.MONTH_NO
, TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
FROM table_a A
, table_b B ON A.identifier = B.identifier
OUTER APPLY (
SELECT
-- variables
MONTH_NO = 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))
) vars
WHERE vars.MONTH_NO > UPD_DATE