[MYSQL] Duplicare riga sulla stessa tabella con ON DUPLICATE KEY | SQL & MySQL

Topic: Pubblico - Composto da 6 Posts di 3 Utenti.

28 Settembre, 2011 09:21 #1
Inevitabile
Utente

Inevitabile
Registrato: Sep, 2011
Posts: 3
Offline

Salve a tutti.
Ho un quesito piuttosto classico che però non riesco a risolvere.
Ho cercato su questo stesso forum ma ho trovato solo un vecchio post di gennaio 2010 dove però si utilizzava un'altra soluzione che non posso applicare.

PROBLEMA: Devo duplicare una riga inserendola nella stessa tabella ma con CHIAVE PRIMARIA DIVERSA dove la chiave primaria è un INT Autoincrement;

SITUAZIONE: Avendo la tabella molte colonne, vorrei NON dover scrivere tutta la insert e la select mappata su tutte le singole colonne ad eccezione dell'ID.

SOLUZIONE NON FUNZIONANTE: Nella mia idea quindi ho utilizzato la classica INSERT su una SELECT e per ovviare al problema dell'ID ho usato ON DUPLICATE KEY. Ecco la query:

1INSERT INTO tabella (
2SELECT * FROM tabella as tab WHERE id = N)
3ON DUPLICATE KEY UPDATE id = (SELECT MAX(id)+1 FROM tabella as tmp)

Il problema infatti risiede nel fatto che ON DUPLICATE KEY lavora sulla riga originale e non sul clone. Lui tenta di clonarla, vede che l'ID è uguale all'originale e la cambia con l'ID che teoricamente dovrebbe avere il clone che quindi NON viene memorizzato.

In pratica sarebbe come scrivere:

1UPDATE tabella SET id = (SELECT MAX(id)+1 FROM tabella as tmp) WHERE id = N

In pratica è come se duplicasse la riga togliendo però l'originale che è come dire che fa un update dell'ID della riga originale.

Quindi vorrei chiedervi come poter risolvere questo problema usando query semplici (anche più di una se serve) che non necessitino di fare una roba tipo:

1INSERT INTO tabella (c1,c2,c3...cN) VALUES (SELECT c1,c2,c3...cN FROM tabella WHERE id=N)

Grazie mille.

Inevitabile

Ultima modifica 28 Settembre, 2011 09:24 di Inevitabile

28 Settembre, 2011 21:58 #2
fuser
Utente

fuser
Registrato: Aug, 2011
Posts: 86
Offline

Poniamo che la tua tabella ha i campi id, a, b, c. id è la chiave primaria ed è l'unico che non deve essere duplicato.

1INSERT INTO tabella SELECT a, b, c FROM tabella WHERE id = 1;

29 Settembre, 2011 11:01 #3
Inevitabile
Utente

Inevitabile
Registrato: Sep, 2011
Posts: 3
Offline

@Fuser: Grazie per avermi risposto ma in fondo al mio messaggio avevo scritto (con un esempio) che questo genere di query non potevo usarla perché la mia tabella ha molte colonne e non voglio esplicitarle tutte.

Ciao.

30 Settembre, 2011 14:52 #4
darasc
Moderatore

darasc
Registrato: Jul, 2010
Posts: 64
Offline

Ciao,

ho trovato una soluzione non propriamente ortodossa ma che dovrebbe risolvere il problema. In pratica il tuo problema è che l'inserimento va a rimpiazzare la riga che stai cercando di clonare, quindi mi sono detto: perchè non inserirla due volte? La prima volta la inserirà col nuovo id mentre la seconda col vecchio id. Ecco come:

1insert into tabella
2
3SELECT tabella.* FROM tabella,(select '2' as a from tabella limit 2)  as tabella2
4
5
6where tabella.id=N and tabella.a='2'  on duplicate key update id= (SELECT MAX(id)+1 FROM tabella)

Quel

1(select '2' as a from tabella limit 2)  as tabella2
l'ho inserito per il semplice motivo che ci permette di raddoppiare le righe da inserire. Magari esiste un altro metodo più pulito ma al momento mi sfugge. Spero sia quello che ti serviva.

Ultima modifica 30 Settembre, 2011 14:53 di darasc

30 Settembre, 2011 15:02 #5
darasc
Moderatore

darasc
Registrato: Jul, 2010
Posts: 64
Offline

Ecco una soluzione più pulita della precedente:

 1insert into tabella
 2
 3SELECT * FROM tabella
 4where tabella.id=N   
 5
 6union all
 7
 8SELECT * FROM tabella
 9where tabella.id=N   
10
11on duplicate key update id= (SELECT MAX(id)+1 FROM tabella)

Come ama dire il buon Algweb: "Se ti serve la stessa riga due volte, fai due volte la stessa query" :D

30 Settembre, 2011 19:54 #6
Inevitabile
Utente

Inevitabile
Registrato: Sep, 2011
Posts: 3
Offline

@Darasc: Funziona benissimo. Grazie mille, se stato un grande!

Condividi su:

Loggati o Registrati per replicare