MODEL Clause

This section presents tutorials on the MODEL clause of the SELECT command. Introduced in Oracle 10g, the MODEL clause is a powerful feature that gives you the ability to change any cell in the query's result set using data from any other cell (similar to the way a spreadsheet works). It also adds procedural features to SQL previously available only through PL/SQL calls.

For example, with MODEL you can take a simple table like this

   KEY GROUP_1    GROUP_2    DATE_VAL   NUM_VAL
------ ---------- ---------- ---------- -------
     1 A          a1         2005-01-01     100
     2 A          a2         2005-06-12     200
     3 A          a3                        300
     4 B          a1         2006-02-01
     5 B          a2         2006-06-12     300
     6 B          a3         2005-01-01     100
     7 C          a1         2006-06-12     100
     8 C          a2
     9            a1         2005-02-01     200
    10            a2         2005-02-01     800
 

and, with a single command, create a report containing ad-hoc totals like this.

set null ""

select
  case when key like 'Total%' then key else null end as total ,
  group_1 ,
  group_2 ,
  num_val
from
  t
model
  dimension by
  (
    cast(key as varchar2(20)) as key ,
    nvl( group_1, 'n/a' )  as group_1 ,
    nvl( group_2, 'n/a' )  as group_2
  )
  measures( num_val )
  rules
  ( num_val[ 'Total 1 - A + C', null, null ] =
      sum(num_val)[any,group_1 in ('A','C'),any]
      ,
    num_val[ 'Total 2 - A + a2', null, null ] =
      sum(num_val)[any,'A',any] +
      sum(num_val)[any,group_1 <> 'A','a2']
      ,
    num_val[ 'Total 3 - n/a', null, null ] =
      sum(num_val)[any,'n/a',any]
      ,
    num_val[ 'Total 4 - a1 + a3', null, null ] =
      sum(num_val)[any,any,group_2 in ('a1','a3')]
  )
order by
  group_1 ,
  group_2 ,
  total nulls first
;
 
TOTAL                GROUP_1    GROUP_2    NUM_VAL
-------------------- ---------- ---------- -------
                     A          a1             100
                     A          a2             200
                     A          a3             300
                     B          a1
                     B          a2             300
                     B          a3             100
                     C          a1             100
                     C          a2
                     n/a        a1             200
                     n/a        a2             800
Total 1 - A + C                                700
Total 2 - A + a2                              1700
Total 3 - n/a                                 1000
Total 4 - a1 + a3                              800
 

You can also use MODEL'S procedural features to produce results that are difficult, inefficient, or impossible to do with a non-MODEL SELECT command. Here is an example.

set null "(null)"
column string format a40

select group_1, substr( string, 2 ) as string
from   t
where  num_val is not null
model
  return updated rows
  partition by ( group_1 )
  dimension by ( row_number() over (partition by group_1 order by num_val) as position )
  measures     ( cast( num_val as varchar2(65) ) as string  ) -- Note 1
  rules
    upsert
    iterate( 6 )
      until ( presentv(string[iteration_number+2],1,0) = 0 )
    ( string[0] = string[0] || ',' || string[iteration_number+1] )
order by group_1 ;
 
GROUP_1    STRING
---------- ----------------------------------------
A          100,200,300
B          100,300
C          100
(null)     200,800
 

(This last technique is explained fully in another section of SQL Snippets at Rows to String: MODEL Method 1.)

Though powerful, the MODEL clause is also somewhat complex and this can be intimidating when you read about it for the first time. The tutorials to follow will therefore present very simple MODEL examples to help you quickly become comfortable with its many features.

Before continuing it is important to know that everything in the MODEL clause is evaluated after all other clauses in the query, except for SELECT DISTINCT and ORDER BY. Knowing this will help you better understand the examples in this section's tutorials.

See Also

Joe's Blog: The Choice




Linking to SQL Snippets ™

To link to this page in Oracle Technology Network Forums or OraFAQ Forums cut and paste this code.

  • [url=http://www.sqlsnippets.com/en/topic-11663.html]SQL Snippets: SQL Features Tutorials - MODEL Clause[/url]

To link to this page in HTML documents or Blogger comments cut and paste this code.

  • <a href="http://www.sqlsnippets.com/en/topic-11663.html">SQL Snippets: SQL Features Tutorials - MODEL Clause</a>

To link to this page in other web sites use the following values.

  • Link Text : SQL Snippets: SQL Features Tutorials - MODEL Clause
  • URL (href): http://www.sqlsnippets.com/en/topic-11663.html

Revision Notes

Date Category Note
2007-05-17 Revision Replaced string aggregation example with a simpler solution.