Oracle SQL - 嵌套子查询未加入主查询

时间:2017-01-12 11:52:29

标签: sql oracle

我在将查询连接到位于某个地方的where子句中的主查询时遇到了麻烦。

在明确定义字段时有效的查询:

SELECT m.field1, m.field2, m.field3, m.myfield, etc etc
(SELECT aa.daysfromprev12 FROM(
  (SELECT subsubm.myfield, MAX(subsubm.date_to)-(SELECT MAX(add_months( to_date(subsubsubm.date_from), -12 )) FROM maintable subsubsubm WHERE subsubsubm.myfield= subsubm.myfield) AS daysfromprev12,
  row_number() OVER (ORDER BY (MAX(subsubm.date_to)-(SELECT MAX(add_months( to_date(subsubsubm.date_from), -12 )) FROM maintable subsubsubm WHERE subsubsubm.myfield= subsubm.myfield)) DESC) rn
  FROM maintable subsubm 
  WHERE subsubm.myfield = '123456'
  GROUP BY subsubm.myfield, subsubm.absence_id) aa) 
where aa.myfield = '123456' and aa.rn = 2)
AS dayss
FROM maintable m
where m.myfield = '123456'

如何替换subsubm.myfield = '123456'& aa.myfield = '123456'引用主要查询= m.myfield

1 个答案:

答案 0 :(得分:1)

在那里的SQL语句中对同一个表的调用太多了。如果我已成功解开你的查询,我认为它可以替换为以下内容:

SELECT field1,
       field2,
       field3,
       field4,
       myfield,
       MAX(CASE WHEN rn = 2 THEN days end) OVER (PARTITION BY myfield) days
FROM   (SELECT field1,
               field2,
               field3,
               field4,
               myfield,
               daysfromprev12 AS days,
               row_number() OVER (ORDER BY daysfromprev12 DESC) rn
        FROM   (SELECT field1,
                       field2,
                       field3,
                       field4,
                       myfield,
                       MAX(date_to) OVER (PARTITION BY myfield, absence_id) -
                         MAX(add_months(TRUNC(date_from), -2)) OVER (PARTITION BY myfield) daysfromprev12
                FROM   maintable
                WHERE  myfield = '123456'));

N.B。未经测试,因为您尚未提供任何样本数据。另外,你假设date_from是DATE数据类型并且你想要摆脱时间部分,我正在做to_date(date_from)我转换为trunc(date_from)。如果它是一个字符串,那么您还需要在to_date()中输入日期格式掩码,以避免发生不必要的隐式转换。

ETA:如果你打算采用这种方法,如果你使用子查询因子(也就是常见的表表达式,也就是CTE)来分离你的子查询,你可能会发现它更容易读/写/维护。例如。上述查询可以重写为:

with get_initial_prev12days as (SELECT field1,
                                       field2,
                                       field3,
                                       field4,
                                       myfield,
                                       MAX(date_to) OVER (PARTITION BY myfield, absence_id) -
                                         MAX(add_months(TRUNC(date_from), -2)) OVER (PARTITION BY myfield) daysfromprev12
                                FROM   maintable
                                WHERE  myfield = '123456'),
            interim_results as (SELECT field1,
                                       field2,
                                       field3,
                                       field4,
                                       myfield,
                                       daysfromprev12 AS days,
                                       row_number() OVER (ORDER BY daysfromprev12 DESC) rn
                                FROM   get_initial_prev12days)
select field1,
       field2,
       field3,
       field4,
       myfield,
       MAX(CASE WHEN rn = 2 THEN days end) OVER (PARTITION BY myfield) days
from   interim_results;