Monday, July 20, 2015

INLINE view in Oracle with 12c New Features


  • Named sub Query in FROM clause is call it as INLINE VIEW.
  • Oracle process a inline view faster than sub query

Inline View in Oracle

--Query to display all the employees who are all getting salary more than their department average salary

SELECT First_name
     , last_name
     , salary
     , department_id
  FROM employees a , ( SELECT b.department_id 
      , AVG(b.salary) avg_sal
           FROM employees b
                              GROUP BY b.department_id
) b
 WHERE a.department_id = b.department_id
   AND a.salary > b.avg_salary;


Display all the customer who have placed more number of orders by using INLINE view


CREATE TABLE customer_order_det_tb
  ( custm_id NUMBER               ,
    custm_nm VARCHAR2(30)         ,
    order_dt DATE DEFAULT SYSDATE ,
    ttl_amt  NUMBER(7,2)  
  );
BEGIN  
  INSERT INTO customer_order_det_tb VALUES(100, 'Murugappan', '11-Jul-15' , 45000.00);
  INSERT INTO customer_order_det_tb VALUES(100, 'Murugappan', '14-Jul-15' , 27000.00);
  INSERT INTO customer_order_det_tb VALUES(101, 'Raja'      , '13-Jul-15' , 17000.00);
  INSERT INTO customer_order_det_tb VALUES(102, 'Ramesh'    , '15-Jul-15' , 34000.00);
  INSERT INTO customer_order_det_tb VALUES(102, 'Ramesh'    , '15-Jul-15' , 38000.00);
  COMMIT;
END;


SELECT c.* 
  FROM customer_order_det_tb c;

--------------------------------------------
custm_id  custm_nm      order_dt    ttl_amt
--------------------------------------------
100       Murugappan 7/11/2015   45000.00
100       Murugappan 7/14/2015   27000.00
101       Raja          7/13/2015   17000.00
102       Ramesh 7/15/2015   34000.00
102       Ramesh 7/15/2015   38000.00
--------------------------------------------

--Writing a Quer to display all the customer who have placed maximum number of order

--Query #1 for inline view
                
  SELECT c.custm_id, c.custm_nm, COUNT(*) total_odr
    FROM customer_order_det_tb c 
GROUP BY c.custm_id,c.custm_nm
ORDER BY total_odr DESC;

--------------------------------
custm_id  custm_nm    total_odr
--------------------------------
     100  Murugappan 2
     102  Ramesh 2  
     101  Raja        1
--------------------------------

--Query #2 for inline view

  SELECT MAX(COUNT(*)) total_odr
    FROM customer_order_det_tb cnt
GROUP BY cnt.custm_id, cnt.custm_nm;

----------
total_odr
----------
     2
----------

Inline view to find all the customers who have placed maximum number of orders

/**************************************** 
Syntax 

SELECT * FROM <query1> x, <query2> y
WHERE contition; 
****************************************/

SELECT query1.* FROM 
         (   SELECT c.custm_id, c.custm_nm, COUNT(*) total_odr
               FROM customer_order_det_tb c 
           GROUP BY c.custm_id,c.custm_nm
           ORDER BY total_odr DESC
         ) query1,
         (   SELECT MAX(COUNT(*)) total_odr
               FROM customer_order_det_tb cnt
           GROUP BY cnt.custm_id, cnt.custm_nm  
         ) query2
WHERE query1.total_odr = query2.total_odr;

-------------------------------
custm_id  custm_nm    total_odr
-------------------------------   
     100  Murugappan
     102  Ramesh 2
-------------------------------

DROP TABLE customer_order_det_tb;

--Display name and salary for top three money makers of the company and their designation should not be SALESMAN and PRESIDENT


SELECT first_name, salary
  FROM (  SELECT first_name, salary
            FROM employees e
           WHERE job_id NOT IN ('SALESMAN','PRESIDENT')
        ORDER BY salary DESC
)
 WHERE ROWNUM < 4;



New Oracle 12c Inline view Syntax


  • LATERAL clause for In-line views
  • Allows for columns in the inline view to be accessed!!

Example :

--in 11g
SELECT * FROM employees e, (
SELECT * 
 FROM departments d
        WHERE e.department_id = d.department_id);

ORA-0090: "E"."DEPARTMENT_ID": Invalid Identifier


--in 12c
SELECT * FROM employees e, LATERAL(
                                    SELECT * 
                                      FROM departments d
            WHERE e.department_id = d.department_id
                                  );


--in 11g
WITH t 
AS              
(   SELECT LEVEL a 
      FROM dual 
CONNECT BY LEVEL <= 30)
        SELECT * 
          FROM t, (SELECT * 
                     FROM employees
                    WHERE department_id = t.a
                  );
                  
ORA-00904: "T"."A": invalid Identifier

--in 12c
WITH t 
AS              
(SELECT LEVEL a FROM dual CONNECT BY LEVEL <= 30)
        SELECT * FROM t,
        LATERAL(SELECT  * 
           FROM employees
          WHERE department_id = t.a); 


Hope you have enjoyed this little article 

                Feed backs are always Welcome :) (:

3 comments:

  1. Use this one

    SELECT First_name, last_name, a.salary, a.department_id FROM hr.employees a , ( SELECT b.department_id , AVG(b.salary) avg_sal FROM hr.employees b GROUP BY b.department_id) b
    WHERE a.department_id = b.department_id AND a.salary > b.avg_sal;

    Its work at my side.

    ReplyDelete
  2. Nice article I was really impressed by seeing this blog, it was very interesting and it is very useful for me.
    SQL Azure Online Training
    Azure SQL Training
    SQL Azure Training

    ReplyDelete
  3. Really nice blog, very infromative. You can refer more topics related to SQL like SQL Commands and PLSQL, PLSQL cursors from here for future articles
    thanks !

    ReplyDelete