Naty Bizz
Naty Bizz

Reputation: 2342

Get multiple columns from a large subquery

I saw a few posts about get columns from subqueries, most of them suggest use a single select for each column, but this is my case

SELECT CAST(p.idvendor AS VARCHAR(10)), CAST(p.description AS VARCHAR(50)),  
(SELECT CAST(NVL(SUM(CASE WHEN locals_sales.cantidad >=0
                           AND locals_sales.cantidad <locals_sales.pqlocals
                     THEN 1 ELSE 0 END), '0') AS VARCHAR(10)) 
   FROM locals_sales, agents, vendors, locals, locals_sales, history
  WHERE locals.idvendor = vendors.idvendor 
    AND locals_sales.IDlocals = locals.idlocals
    AND agents.codagente=vendors.codagente
    AND agents.idagent!=1
    AND locals_sales.number_n_line = locals_sales.n_line
    AND locals.estado=1
    AND vendors.idvendor = p.idvendor
    AND history.number_line(+) = locals_sales.n_line
    AND history.date(+) >= to_date('4/9/2012 00:00', 'dd/mm/yy HH24:mi:ss')
 ) AS critic, 
(SELECT CAST(NVL(SUM(CASE WHEN locals_sales.cantidad >=locals_sales.pqlocals
                           AND locals_sales.cantidad <locals_sales.media
                     THEN 1 ELSE 0 END), '0') AS VARCHAR(10))
   FROM locals_sales, agents, vendors, locals, locals_sales, history
  WHERE locals.idvendor = vendors.idvendor
    AND locals_sales.IDlocals = locals.idlocals
    AND agents.codagente=vendors.codagente
    AND agents.idagent!=1
    AND locals_sales.number_n_line = locals_sales.n_line
    AND locals.estado=1
    AND vendors.idvendor = p.idvendor
    AND history.number_line(+) = locals_sales.n_line
    AND history.date(+) >= to_date('4/9/2012 00:00', 'dd/mm/yy HH24:mi:ss')
 ) AS medium, 
(SELECT CAST(NVL(SUM(CASE WHEN locals_sales.cantidad >=locals_sales.media
                     THEN 1 ELSE 0 END), '0') AS VARCHAR(10))
   FROM locals_sales, agents, vendors, locals, locals_sales, history
  WHERE locals.idvendor = vendors.idvendor
    AND locals_sales.IDlocals = locals.idlocals
    AND agents.codagente=vendors.codagente
    AND agents.idagent!=1
    AND locals_sales.number_n_line = locals_sales.n_line
    AND locals.estado=1
    AND vendors.idvendor = p.idvendor
    AND history.number_line(+) = locals_sales.n_line
    AND history.date(+) >= to_date('4/9/2012 00:00', 'dd/mm/yy HH24:mi:ss')
 ) AS NORMAL 
 FROM vendors p, agents ag
WHERE ag.codagente=p.codagente

As you can see I have three SUM for each column, these columns are from the same tables, the difference comes from my preconditions in each CASE of each select

Also, almost the end of each select I have this as condition

vendors.idvendor = p.idvendor

p is the alias of the table outside of the subquery

How can I avoid use three selects almost similar and use instead a single select for the 3 columns in order to improve the performance?

Upvotes: 0

Views: 464

Answers (1)

Gordon Linoff
Gordon Linoff

Reputation: 1270391

You can handle this by moving the subqueries into the FROM clause and doing a proper join.

The final query will look like:

select CAST(p.idvendor AS VARCHAR(10)), CAST(p.description AS VARCHAR(50)),
       s.val1, s.val2, sl.val3
from vendors p join
     agents ag 
     on p.codeagent = ag.codeagent join
     (<a variation of your subquery here with all three columns defined and idvendor in the select list>
     ) s
     on p.idvendors= s.idvendor

Also, to make your queries more readable, you should really use proper join syntax.

Upvotes: 1

Related Questions