简体   繁体   中英

Oracle SQL - Nested sub query not joining to main query

I'm having real trouble getting the sub query join to the main query in the where clause somewhere along the way.

Query that works when explicitly defining the field:

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'

How can I replace subsubm.myfield = '123456' & aa.myfield = '123456' to reference the main query = m.myfield

There are way too many calls to the same table in your SQL statement there. If I've managed to unwind your query ok, I think it can be replaced with the following:

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'));

NB Untested, since you haven't provided any sample data to work with. Also, you were doing to_date(date_from) which I have converted to trunc(date_from) on the assumption that date_from is of DATE datatype and you wanted to get rid of the time part. If it's a string, then you'd need to also input the date format mask in the to_date() to avoid the unnecessary implicit conversion taking place.


ETA: If you're going to go with this approach, you would probably find it easier to read/write/maintain if you use subquery factoring (aka common table expressions aka CTE) to separate out your subqueries. Eg the above query could be rewritten as:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM