Small. Fast. Reliable.
Choose any three.
What is?

SQL is a very capable language and there are very few questions that it cannot answer. I find that I can come up with some convoluted SQL query to answer virtually any question you could ask from the data. However, the performance of some of these queries is not what it should be - nor is the query itself easy to write in the first place. Some of the things that are hard to do in straight SQL are actually very commonly requested operations, including:

Both the "Top-N" and ranking queries could perhaps be implemented by simply having a result row number be returned (after sorting). The row number can then be used to calculate positional-based info. It would be similar to Oracle's "rownum" pseudo-column, but without the limits of Oracle's take.

Analytic functions, are designed to address these issues. They add extensions to the SQL language that not only make these operations easier to code; they make them faster than could be achieved with the pure SQL approach. These extensions are currently under review by the ANSI SQL committee for inclusion in the SQL specification.

The syntax of the analytic function is rather straightforward in appearance, but looks can be deceiving. It starts with:

        FUNCTION_NAME(<argument>,<argument>,?)
        OVER
        (<Partition-Clause> <Order-by-Clause> <Windowing Clause>)

        create table sum_example (
                                 dt date,
                                 xy number
                                );

	insert into sum_example values (to_date('27.08.1970','DD.MM.YYYY'),4);
	insert into sum_example values (to_date('02.09.1970','DD.MM.YYYY'),1);
	insert into sum_example values (to_date('09.09.1970','DD.MM.YYYY'),5);
	insert into sum_example values (to_date('26.08.1970','DD.MM.YYYY'),3);
	insert into sum_example values (to_date('28.08.1970','DD.MM.YYYY'),4);
	insert into sum_example values (to_date('26.08.1970','DD.MM.YYYY'),6);
	insert into sum_example values (to_date('29.08.1970','DD.MM.YYYY'),9);
	insert into sum_example values (to_date('30.08.1970','DD.MM.YYYY'),2);
	insert into sum_example values (to_date('12.09.1970','DD.MM.YYYY'),7);
	insert into sum_example values (to_date('23.08.1970','DD.MM.YYYY'),2);
	insert into sum_example values (to_date('27.08.1970','DD.MM.YYYY'),5);
	insert into sum_example values (to_date('09.09.1970','DD.MM.YYYY'),9);
	insert into sum_example values (to_date('01.09.1970','DD.MM.YYYY'),3);
	insert into sum_example values (to_date('07.09.1970','DD.MM.YYYY'),1);
	insert into sum_example values (to_date('12.09.1970','DD.MM.YYYY'),4);
	insert into sum_example values (to_date('03.09.1970','DD.MM.YYYY'),5);
	insert into sum_example values (to_date('03.09.1970','DD.MM.YYYY'),8);
	insert into sum_example values (to_date('07.09.1970','DD.MM.YYYY'),7);
	insert into sum_example values (to_date('04.09.1970','DD.MM.YYYY'),8);
	insert into sum_example values (to_date('09.09.1970','DD.MM.YYYY'),1);
	insert into sum_example values (to_date('29.08.1970','DD.MM.YYYY'),3);
	insert into sum_example values (to_date('30.08.1970','DD.MM.YYYY'),7);
	insert into sum_example values (to_date('24.08.1970','DD.MM.YYYY'),7);
	insert into sum_example values (to_date('07.09.1970','DD.MM.YYYY'),9);
	insert into sum_example values (to_date('26.08.1970','DD.MM.YYYY'),2);
	insert into sum_example values (to_date('09.09.1970','DD.MM.YYYY'),8);

        select dt,
               sum(xy) over (partition by trunc(dt) order by dt rows between
                  unbounded preceding and current row) s,
               xy
        from sum_example;

        drop table sum_example;

        sum(xy) over (partition by trunc(dt) order by dt rows between unbounded preceding and current row)

23.08.70 2 2
24.08.70 7 7
26.08.70 3 3
26.08.70 5 2
26.08.70 11 6
27.08.70 4 4
27.08.70 9 5
28.08.70 4 4
29.08.70 9 9
29.08.70 12 3
30.08.70 2 2
30.08.70 9 7
01.09.70 3 3
02.09.70 1 1
03.09.70 5 5
03.09.70 13 8
04.09.70 8 8
07.09.70 1 1
07.09.70 8 7
07.09.70 17 9
09.09.70 5 5
09.09.70 14 9
09.09.70 15 1
09.09.70 23 8
12.09.70 7 7
12.09.70 11 4

A list of analytic functions we could find in Oracle Express 10:

This list of function is often used to improve performance :

A few of these functions on SQLite are supported through Perl's SQLite::More module.