È possibile aggiungere simlpe SERIAL
colonna alla tabella (lo farà dare l'ordine per le cose) e quindi utilizzare qualcosa del tipo:
SELECT *, row_number() OVER (PARTITION BY month ORDER BY serial_column)
FROM table
Questo vi darà e risultati che vuoi
Se non avete bisogno di ordinare le righe, si può provare:
SELECT *, row_number() OVER (PARTITION BY month)
FROM table
dettagli qui: row_number() OVER(...)
UPD Come funziona:
Una colonna di tipo SERIAL
è essenzialmente un campo "auto increment". Ottiene automaticamente un valore da una sequenza. Quando si inserisce righe alla tabella che sarà simile a questo:
| MONTH | SERIAL_COLUMN | DESCRIPTION |
-----------------------------------------------------------
| 1 | 1 | One thing |
| 1 | 2 | Another thing |
| 1 | 3 | Last task of the month |
| 2 | 4 | First of second month |
| 2 | 5 | Second and last of second month |
| 3 | 6 | First of third month |
La cosa fondamentale - ogni riga aggiunta accanto ha un valore di SERIAL_COLUMN
maggiore di tutte le righe precedenti.
Avanti. Il row_number() OVER (PARTITION BY month ORDER BY serial_column)
fa:
1) divisorie tutte le righe in gruppi con uguale month
(PARTITION BY month
)
2) ordina loro per valore di serial_column
(ORDER BY serial_column
)
3) In ogni gruppo assegna un numero di riga utilizzando l'ordinamento dal passo 2 (`row_number() OVER
)
il risultato è:
| MONTH | SERIAL_COLUMN | DESCRIPTION | ROW_NUMBER |
------------------------------------------------------------------------
| 1 | 1 | One thing | 1 |
| 1 | 2 | Another thing | 2 |
| 1 | 3 | Last task of the month | 3 |
| 2 | 4 | First of second month | 1 |
| 2 | 5 | Second and last of second month | 2 |
| 3 | 6 | First of third month | 1 |
Per modificare l'output di row_number()
è necessario modificare i valori in SERIAL_COLUMN
. Fro esempio, di inserire il Second and last of second month
prima First of second month
un cambierà i valori di SERIAL_COLUMN
così:
UPDATE Table1
SET serial_column = 5
WHERE description = 'First of second month';
UPDATE Table1
SET serial_column = 4
WHERE description = 'Second and last of second month';
Cambierà l'output della query:
| MONTH | SERIAL_COLUMN | DESCRIPTION | ROW_NUMBER |
------------------------------------------------------------------------
| 1 | 1 | One thing | 1 |
| 1 | 2 | Another thing | 2 |
| 1 | 3 | Last task of the month | 3 |
| 2 | 4 | Second and last of second month | 1 |
| 2 | 5 | First of second month | 2 |
| 3 | 6 | First of third month | 1 |
I valori esatti in SERIAL_COLUMN
non contano. Impostano solo un ordine sulle attività in un mese.
Il mio esempio SQLFiddle è here.
Questo è il modo per farlo. In un ambiente multiutente è * molto difficile * far rispettare la numerazione senza spazio senza creare ** condizioni di gara **. Dovresti usare i blocchi del tavolo pesantemente, il che è un vero fattore negativo per le prestazioni. Ti suggerisco di usare 'row_number()' invece di 'rank()'. Il risultato è lo stesso in assenza di peer (come in questo caso), ma 'row_number()' è la funzione più economica e più appropriata. –
@ErwinBrandstetter Grazie per 'row_number()'. Ho modificato le query. –
Posso in seguito cambiare l'ordine delle attività in un mese? – Mario