tags:

views:

84

answers:

2

I have the following table in an Oracle database:

InvoiceNumber InvoiceDate InvoiceCorrelative
------------- ----------- ------------------
          123  02-03-2009                  0
          124  02-03-2009                  0
          125  02-04-2009                  0
          126  02-04-2009                  0
          127  02-04-2009                  0
          128  02-05-2009                  0
          129  02-06-2009                  0
          130  02-06-2009                  0
          ...         ...                ...

And I want to set a value for the InvoiceCorrelative column in every row in order to have a sequence of numbers starting at 1 for each date. In the example above I want the table to look like this:

InvoiceNumber InvoiceDate InvoiceCorrelative
------------- ----------- ------------------
          123  02-03-2009                  1
          124  02-03-2009                  2
          125  02-04-2009                  1
          126  02-04-2009                  2
          127  02-04-2009                  3
          128  02-05-2009                  1
          129  02-06-2009                  1
          130  02-06-2009                  2
          ...         ...                ...

Is it possible to do it only using SQL statements?. I've been playing with rownum but didn't get anywhere.

+9  A: 

Try:

ROW_NUMBER() OVER (PARTITION BY InvoiceDate ORDER BY InvoiceNumber)
Andomar
This will work with MSSQL but looking at the tag, the asker is using Oracle.
Josh Smeaton
Quick look says ROW_NUMBER() is supported in Oracle 10g+, but DENSE_RANK is 9i: http://techonthenet.com/oracle/functions/dense_rank.php
OMG Ponies
@Josh Smeaton: I think Oracle invented analytic functions and Microsoft copied them @OMG Ponies: interesting link!
Andomar
row_number() works in ora9
Khb
9i had the RANK(), DENSE_RANK(), and ROW_NUMBER() analytic functions. The only difference between the three are how they handle ties. ROW_NUMBER returns a unique value for each row, arbitrarily breaking ties. RANK gives ties the same value and skips subsequent values, as you would do in an athletic competition. If there is a tie for first, the next competitor gets third place. DENSE_RANK eliminates the gaps while giving ties the same value so that if there is a tie for first the next row gets a value of 2.
Justin Cave
Excellent!!! Exactly what I needed.
Toto
+4  A: 

Using Standard SQL,

  Update TabkleName T Set
    InvoiceCorrelative = 
     (Select Count(*) From TableName 
      Where InvoiceDate = T.InvoiceDate
        And InvoiceNumber <= T.InvoiceNumber)
Charles Bretana