You are on page 1of 2

# Analytic Functions Analytic functions compute an aggregate value based on a group of rows.

They dif fer from aggregate functions in that they return multiple rows for each group. Analytic functions are the last set of operations performed in a query except fo r the final ORDER BY clause. All joins and all WHERE, GROUP BY, and HAVING claus es are completed before the analytic functions are processed. Therefore, analyti c functions can appear only in the select list or ORDER BY clause. Analytic functions Syntax :analytic_function(arguments) over (query_partition_by Order_by_clause)

Use OVER analytic_clause to indicate that the function operates on a query resul t set. That is, it is computed after the FROM, WHERE, GROUP BY, and HAVING claus es. You can specify analytic functions with this clause in the select list or ORDER BY clause. To filter the results of a query based on an analytic function, nest these funct ions within the parent query, and then filter the results of the nested sub-quer y. query_partition_by Use the PARTITION BY clause to partition the query result set into groups based on one or more value_expr. If you omit this clause, then the function treats all rows of the query result set as a single group. example : sum(sal) over ( partition by deptno,mgrno) Order_by_clause Use the order_by_clause to specify how data is ordered within a partition. ASC | DESC Specify the ordering sequence (ascending or descending). ASC is the d efault. NULLS FIRST | NULLS LAST Specify whether returned rows containing nulls should a ppear first or last in the ordering sequence. NULLS LAST is the default for ascending order, and NULLS FIRST is the default fo r descending order. example : sum(sal) over ( partition by deptno,mgrno order by empno DESC NULLS FI RST ) Analytic functions always operate on rows in the order specified in the order_by _clause of the function. However, the order_by_clause of the function does not g uarantee the order of the result. Use the order_by_clause of the query to guaran tee the final result ordering. analytic_function AVG COUNT FIRST FIRST_VALUE LAG LAST LAST_VALUE

LEAD MAX MIN RANK ROW_NUMBER SUM VARIANCE I will clarify later using of that functions in part 2. Hint For IT people who use Microsoft SQL Server, It is the same syntax. Unfortunately Mysql doesn't support partition by clause. /******************************************************************************* */* /* The following is comment on challenge indicated to the previoud topic /* /******************************************************************************* */ I created challenge at my Facebook wall that indicated to that topic. Challenge Question I want select statement that show employees and his serial in his department like the following EmpNO ENAME DeptNO Serial 7782 "CLARK" 10 1 7839 "KING" 10 2 7369 "SMITH" 20 1 7566 "JONES" 20 2 7499 "ALLEN" 30 1 7521 "WARD" 30 2 Challenge Solution 1- First solution that uses partition by clause (Oracle RDBMS and Microsoft SQL Server) SELECT empno, ename, deptno, COUNT (deptno) OVER (PARTITION BY deptno ORDER BY empno) FROM scott.emp 2- Second solution that uses left outer join and that solution have bad performa nce. ( SQL Standard ) SELECT a.empno, a.ename, a.deptno, COUNT (*) serial FROM scott.emp a LEFT OUTER JOIN scott.emp b ON a.deptno = b.deptno AND a.empno >= b.empno GROUP BY a.empno, a.ename, a.deptno ORDER BY a.deptno, a.empno 3- Third solution that can be executed at Mysql only set @deptartment = 0; set @serial = 1; select empno, ename, deptno @serial := if(@deptartment = deptno, @serial + 1, 1) as row_number, @deptartment := deptno as dummy from scott.emp order by deptno,empno;