2015-12-17 21 views
6

Voglio mostrare una colonna personalizzata come alias, ma è necessario incrementare utilizzando il carattere automatico.Come creare una colonna personalizzata con caratteri di incremento automatico

id  subid dollar packetname 
168  355  5813 ND-1 
169  355  359  ND-1 
170  356  559  ND-2 
171  362  4536 ND-10 
172  362  484  ND-10 
134  329  4698 ND-12 
135  329  435  ND-12 
125  330  6293 ND-13 
126  330  4293 ND-13 
127  330  693  ND-13 

Ho bisogno di un uscita con un altro pacchetto aggiornato. colonna con carattere autoincrement

id  subid dollar packetname  updated packet 
168  355  5813 ND-1   ND-1 
169  355  359  ND-1   ND-1A 
170  356  559  ND-2   ND-2 
171  362  4536 ND-10   ND-10 
172  362  484  ND-10   ND-10A 
134  329  4698 ND-12   ND-12 
135  329  435  ND-12   ND-12A 
125  330  6293 ND-13   ND-13 
126  330  4293 ND-13   ND-13A 
127  330  693  ND-13   ND-13B 
+2

Hmm, supponiamo colonna 37a sarà 'ND-13Z', quello che ci si aspetta di essere 38 °? – Timekiller

+0

@Timekiller no Non mi aspetto nulla al 38 °. Il mio requisito massimo è solo da A a G. –

risposta

2

È possibile utilizzare tale query per fare ulteriore campo

SELECT concat(packetname, 
       elt(if(@t=packetname, @n:[email protected]+1, @n:=1), 
        '','A','B','C','D','E','F','G')) `updated packet`, 
     id, subid, dollar, @t:=packetname packetname 
    FROM t 
     cross join 
     (SELECT @n:=1, @t:="") n 
    order by packetname 

demo on sqlfiddle

2

penso che la soluzione migliore è quella di SELECT la tabella pacchetto corrente, modificandolo lungo la strada, e INSERT in una nuova tabella. Una volta completata questa operazione, è possibile rilasciare la tabella originale e quindi rinominare quella nuova con quella precedente.

INSERT INTO newpacket (id, subid, dollar, packetname, `updated packet`) 
SELECT p1.id, p1.subid, p1.dollar, p1.packetname, p2.`updated packet` 
FROM packet p1 
INNER JOIN 
(
    SELECT p.id, p.subid, 
     CASE WHEN (SELECT p.id - MIN(t.id) FROM packet t WHERE t.subid = p.subid) > 0 
     THEN CONCAT(packetname, 
        CHAR(((SELECT p.id - MIN(t.id) FROM packet t WHERE t.subid = p.subid) + 64) USING utf8)) 
     ELSE packetname END AS `updated packet` 
    FROM packet p 
) p2 
ON p1.subid = p2.subid AND p1.id = p2.id 
+0

Si prega di dare questa query aggiornata una prova. –

+0

È sicuro operare su 'id' /' subid'? Cosa succede se i valori di 'id' sono sparsi nei dati reali? Cosa succede se ci sono gli stessi 'packetname' per diversi' subid'? – Timekiller

+0

@TimBiegeleisen non funziona ancora. –

1

È possibile creare un trigger.

create trigger my_trigger before insert on mytable for each row 
begin 
DECLARE samecount INT; 
    set samecount = (select count(*) from mytable where packetname = new.packetname); 
    if samecount = 0 then 
    set new.updated_packet = new.packetname; 
    else 
    set new.updated_packet = concat(new.packetname,conv(samecount+9,10,36)); 
    end if; 
end; 

Prima che una nuova riga è inserita, conta come esistono molte righe con stesso packetname. Quando ce n'è uno o più, il conteggio + 9 viene convertito in base 36 - è quasi lo stesso di HEX tranne che fino a Z. Quindi, se il conteggio è 1, diventa 1+9=10=A. Il valore risultante è concatenato con packetname. Se le stesse righe superano 37, non fallirà, ma aggiungerà invece 10 per 38.

Ricordare che questo non è esattamente auto increment e potrebbe essere soggetto a condizioni di gara, quando due utenti inseriscono lo stesso packetname esattamente nello stesso momento, la query di conteggio può restituire lo stesso valore per entrambi.

EDIT: Si noti che questa soluzione per quando avrete bisogno di inserire nuovi righe in quella tabella dopo e voglio che abbiano updated_packet riempiti automaticamente. Se si desidera aggiornare anche le righe esistenti, in un modo è quello di creare una nuova tabella con stessa struttura, creare che si innescano quando una nuova tabella e poi fare

insert into newtable(id, subid, dollar, packetname) 
select id, subid, dollar, packetname from oldtable