Pythonisti, come faccio a spostare i dati da cima a fondo per da sinistra a destra in MySQL (si pensi più valori per ogni ID)?

StackOverflow https://stackoverflow.com/questions/4088639

  •  28-09-2019
  •  | 
  •  

Domanda

operazione attuale è quello di spostare i dati come mostrato nella tabella 1 a quella della tabella 2.

Tabella (1)

ID  Val
--  ---
1   a
1   b
1   c
2   k
3   l
3   m 
3   n

colonne Val dipendono dal numero di valori unici per ogni ID. in questo caso si tratta di 3, ma può essere di 20 nel mondo reale!

Tabella (2)

ID  Val1 Val2 Val3  
--  --   --   --
1   a    b    c
2   k
3   l    m    n

Come posso affrontare per valori minori di colonne Val (3 in questo caso):

I creare una tabella temporanea.

create table test(ID int not null, b int auto_increment not null,primary key(ID,b), Val varchar(255));

I quindi inserire i dati in a test.

ottengo il seguente (devo creare le colonne Val manualmente):

ID  Val  b
--  ---  --
1   a    1
1   b    2
1   c    3
2   k    1
3   l    1
3   m    2
3   n    3

So che questo è un processo noioso con molto lavoro manuale. Questo era prima che mi sono innamorato con Python! Una soluzione efficiente in Python per questo problema è molto apprezzato!

Questo è quello che ho finora

import MySQLdb
import itertools
import dbstring

cursor = db.cursor()

cursor.execute("select ID, val from mytable")
mydata = cursor.fetchall()

IDlist = []
vallist = []
finallist = []

for record in mydata:
    IDlist.append(record[1])
    vallist.append(record[2])

zipped = zip(IDlist,vallist)
zipped.sort(key=lambda x:x[0])

for i, j in itertools.groupby(zipped, key=lambda x:x[0]):
    finallist = [k[1] for k in j]
finallist.insert(0, i)
finallist += [None] * (4 - len(finallist))  ### Making it a uniform size list
    myvalues.append(finallist)

cursor.executemany("INSERT INTO temptable VALUES (%s, %s, %s, %s)", myvalues)


db.close()
È stato utile?

Soluzione

il modo pytonic per farlo è quello di utilizzare itertools.groupby

import itertools

a = [(1, 'a'), (1, 'b'), (2, 'c')]

# groupby need sorted value so sorted in case
a.sort(key=lambda x:x[0])

for i, j in itertools.groupby(a, key=lambda x:x[0]):
    print i, [k[1] for k in j]

ritorno

1 ['a', 'b']
2 ['c']
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top