如何在主选择中使用嵌套选择中的列值?

Posted

技术标签:

【中文标题】如何在主选择中使用嵌套选择中的列值?【英文标题】:How can I use columns value from nested select in main select? 【发布时间】:2015-02-09 15:55:58 【问题描述】:

我正在尝试在 Oracle 中执行此 SQL:

select z.*
  from (select (CASE
                 WHEN trunc(to_date('01.02.2015', 'DD.MM.YY'), 'MM') =
                      to_date('01.02.2015', 'DD.MM.YY') THEN
                  trunc(ADD_MONTHS(sysdate, -1), 'MM')
                 ELSE
                  trunc(sysdate - 1)
               END) as sd,
               trunc(sysdate) ed
          from dual) t,
       (SELECT *
          FROM table(SOMEOWNERUSER.SOMEPACKAGE.getPipelinedTable(to_char(t.sd,
                                                                       'dd.mm.yyyy'),
                                                               to_char(t.ed,
                                                                       'dd.mm.yyyy')))) z

但我收到错误 ORA-00904: "T"."SD": invalid identifier。我做错了什么?

【问题讨论】:

尝试摆脱整个查询from dual。只需在 getPipelinedTable 调用中使用 case 表达式。您不能以这种方式跨查询引用列。 SQL Server 有cross apply,但我不知道Oracle 是否有等价物。我不认为你需要它。如果这不起作用,您可能只需要使用要传递的参数初始化一些变量。 您在第二个子查询中对列 t.sd 和 t.ed 的引用导致错误。您需要将您的第二个子查询与 t 的结果相关联。 【参考方案1】:

你只需要在t子查询的同级join中直接引用table()即可:

create type dt_type as object (dt date);
/

create type dt_tab as table of dt_type;
/

create or replace function getpipelinedtable (p_sd date, p_ed date)
return dt_tab
as
  l_tab dt_tab := dt_tab();
begin
  for i in 1 .. (p_ed - p_sd) + 1
  loop
    l_tab.extend;
    l_tab(l_tab.last) := dt_type(p_sd -1 + i);
  end loop;

  return l_tab;
end getpipelinedtable;
/

SELECT z.*
FROM   (SELECT (CASE WHEN TRUNC (TO_DATE ('01.02.2015', 'DD.MM.YY'), 'MM') = TO_DATE ('01.02.2015', 'DD.MM.YY') 
                          THEN TRUNC (ADD_MONTHS (SYSDATE, -1), 'MM') 
                     ELSE TRUNC (SYSDATE - 1) 
                END) AS sd,
                TRUNC (SYSDATE) ed
        FROM   DUAL) t,
        TABLE (  getpipelinedtable (t.sd, t.ed) ) z;

DT        
----------
01/01/2015
02/01/2015
03/01/2015
04/01/2015
05/01/2015
<snip>
06/02/2015
07/02/2015
08/02/2015
09/02/2015

drop function getpipelinedtable;
drop type dt_tab;
drop type dt_type;

【讨论】:

Boneist,非常感谢你!就是这个。接下来我的问题是“如果从 some_table 中选择 * 而不是 TABLE(someFunc()),如何做同样的事情?”。但是,我知道需要使用 INNER JOIN:... t, inner join some_join_table jt on jt.created &gt;= t.sd and jt.created &lt; t.ed 是的,您可以进行内部联接(尽管您会在 t 之后和 inner join 之前删除逗号)。这完全取决于您要达到的目标。 是的,我忘了在t 之后删除逗号。谢谢。

以上是关于如何在主选择中使用嵌套选择中的列值?的主要内容,如果未能解决你的问题,请参考以下文章

如何比较按一列分组的 SQL 中的列值?

如何使用 JPA 原生查询选择多个同名的列?

过滤不在选择中的列值

如何将具有嵌套StructType的列转换为Spark SQL中的类实例?

在 SQL 中选择具有唯一列值的行

如何根据数据框中的列值获取特定的行数[重复]