2009-10-21 10 views
9

Sto lavorando su qualche codice/database legacy e devo aggiungere un campo al database che registrerà un numero di sequenza relativo a quell'id (straniero).MySQL: aggiungi colonna di sequenza in base a un altro campo

dati della tabella Esempio (correnti):

ID  ACCOUNT  some_other_stuff 
1  1   ... 
2  1   ... 
3  1   ... 
4  2   ... 
5  2   ... 
6  1   ... 

ho bisogno di aggiungere una colonna sequenceid che incrementa separatamente per ciascun conto, ottenendo:

ID  ACCOUNT  SEQ  some_other_stuff 
1  1   1  ... 
2  1   2  ... 
3  1   3  ... 
4  2   1  ... 
5  2   2  ... 
6  1   4  ... 

noti che la sequenza è legato alla considerazione.

C'è un modo per ottenerlo in SQL o ricorrere a uno script PHP per fare il lavoro per me?

TIA, Kev

risposta

6

Questo dovrebbe funzionare ma è probabilmente lento:

CREATE temporary table seq (id int, seq int); 
INSERT INTO seq (id, seq) 
    SELECT id, 
     (SELECT count(*) + 1 FROM test c 
     WHERE c.id < test.id AND c.account = test.account) as seq 
    FROM test; 

UPDATE test INNER join seq ON test.id = seq.id SET test.seq = seq.seq; 

Ho chiamato la tabella 'test'; ovviamente questo deve essere impostato correttamente. Devi usare una tabella temporanea perché MySQL non ti consente di usare una sottoselezione dalla stessa tabella che stai aggiornando.

+0

@tom haigh can per favore spiega come funziona? – FBP

4

La domanda è etichettato come "mysql", quindi sì, auto_increment di MySQL può creare ID sequenziali GroupWise.
vedere http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html:

Per MyISAM e BDB tabelle è possibile specificare AUTO_INCREMENT su una colonna secondaria in un indice a più colonne. In questo caso, il valore generato per la colonna AUTO_INCREMENT viene calcolato come MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. Questo è utile quando vuoi mettere i dati in gruppi ordinati.

edit: esempio di script PHP (usando PDO, ma è lo stesso gioco con il modulo php-mysql)

$pdo = new PDO('mysql:host=...;dbname=...', '...', '...'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

// example table 
$pdo->exec(
    'CREATE TEMPORARY TABLE Foo (
    id int auto_increment, 
    account int, 
    someotherstuff varchar(32), 
    primary key(account,id) 
) engine=MyIsam' 
); 
// insert example data 
$stmt = $pdo->prepare('INSERT INTO Foo (account,someotherstuff) VALUES (?,?)'); 
$stmt->execute(array(1, '1a')); 
$stmt->execute(array(1, '1b')); 
$stmt->execute(array(1, '1c')); 
$stmt->execute(array(2, '2a')); 
$stmt->execute(array(2, '2b')); 
$stmt->execute(array(1, '1d')); 
unset($stmt); 

// query data 
foreach($pdo->query('SELECT account,id,someotherstuff FROM Foo') as $row) { 
    echo $row['account'], ' ', $row['id'], ' ', $row['someotherstuff'], "\n"; 
} 

stampe

1 1 1a 
1 2 1b 
1 3 1c 
2 1 2a 
2 2 2b 
1 4 1d 
+0

Grazie per la risposta. Scusa - avrei dovuto specificare le tabelle innoDB. Alla fine ho optato per la soluzione dei tavoli temporanei di seguito, ma apprezzo l'input! Saluti! –

+0

Soluzione piacevole. Questa è la risposta corretta. funziona alla grande. – SuB

5

creare un trigger:

CREATE TRIGGER trg_mytable_bi 
BEFORE INSERT ON mytable 
FOR EACH ROW 
BEGIN 
     DECLARE nseq INT; 
     SELECT COALESCE(MAX(seq), 0) + 1 
     INTO nseq 
     FROM mytable 
     WHERE account = NEW.account; 
     SET NEW.seq = nseq; 
END; 
+0

Supponendo che l'OP abbia MySQL 5 ... – Ben

+0

Grazie per la vostra risposta, ma alla fine sono andato per la soluzione temporanea di tabelle sopra. –

+0

Per chiunque abbia problemi con errori di confusione, vedere qui sull'utilizzo dei delimitatori nel trigger: http://stackoverflow.com/questions/5814153/error-in-your-sql-syntax-creating-mysql-trigger – Druckles

Problemi correlati