简体   繁体   中英

how can I join two queries in which one is derived from other?

Could somebody explain me whats wrong in this? My query is like this...

select t1.year, t1.empid, t2.tcost
from (select year,empid,sum(cost) as total from orders group by year,empid) t1
inner join (select year, max(total) from t1 group by year) t2
on t1.year= t2.year

I am getting error message as below

ERROR at line 3:

ORA-00942: table or view does not exist

I know I can achieve this using WITH clause but I want to know how to use join in this case.

Thanks in advance

If in your query you use self-join, there is usually an equivalent query based on analytical functions. The advantage is, in most cases, shorter execution time. Here you could use max ... keep dense rank ... :

select year, empid, sum_cost 
  from (
    select year, empid, sum(cost) sum_cost,
           max(sum(cost)) keep (dense_rank last order by sum(cost)) 
                          over (partition by year) max_cost
      from orders group by year, empid )
  where sum_cost = max_cost

Sample data and output:

create table orders (year number(4), empid number(5), cost number(10,2));
insert into orders values (2010, 1, 100);
insert into orders values (2010, 1, 115);
insert into orders values (2010, 1, 207);
insert into orders values (2010, 2, 104);
insert into orders values (2011, 1,  90);
insert into orders values (2011, 2,  15);
insert into orders values (2011, 2, 107);
insert into orders values (2011, 3, 100);

Output:

YEAR  EMPID  SUM_COST
----  -----  --------
2010      1       422
2011      2       122

Edit: I doubt you could eliminate with clause if you want to do self-join here. with is used especially when complex sub-queries are used twice or more. And if you insist on join instead of where (year,tcost) in ... , as you suggested in of the comments, please use:

with vvn as (select year, empid, sum(cost) as sc from orders group by year, empid) 
  select v1.year, v1.empid, v1.sc from vvn v1
    join (select year, max(sc) msc from vvn group by year) v2 
      on v1.year = v2.year and v1.sc = v2.msc;

BTW, shortened version of my first answer does not really need keep dense rank part, simpler is:

select year, empid, sum_cost 
  from (select year, empid, sum(cost) sum_cost,
               max(sum(cost)) over (partition by year) max_cost
          from orders group by year, empid )
  where sum_cost = max_cost

Version with somehwat modified keep... is still valid and interesting, but you probably noticed this.

SELECT t1.year, t1.empid, t2.tcost
FROM (SELECT year, empid, sum(cost) AS total
      FROM orders
      GROUP BY year, empid) t1
     INNER JOIN (SELECT year, max(total) **AS tcost**
                 FROM t1 **<-- ?? No, you need to specify a table**
                 GROUP BY year) t2
         ON t1.year = t2.year

You have a comma between t1 and INNER, and syntax is wrong in FROM T1, you cannot JOIN an inner table to another inner. Also max(total) needs to be aliased. All shown above.

Try this

select t.year, t.empid, t.total
from (select t1.year,t1.empid,sum(t1.cost) as total from orders as t1  
inner join orders as t2 on t1.year= t2.year  group by t1.year,t1.empid) t

SQL JOINing a Table to Itself

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