Topic: Somma di alcune colonne  (Letto 279 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline tascio

  • python erectus
  • ***
  • Post: 175
  • Punti reputazione: 0
    • Mostra profilo
Somma di alcune colonne
« il: Gennaio 24, 2019, 11:52 »
Avendo un db d'esempio tipo questo:
ID   NOME   TIZIO   CAIO   SEMPRONE
1     pippo      5          9               2
2     ciccio       2          1              10
3     nino         4           2             1
4     pippo       2          1              10
5     pippo       6          2               1

Come si fa a fare una sorta di self join che mi ritorni un GROUP BY 'nome' con le somme delle colonne.
Cioè vorrei che al classico
for row in cursor.fetchall():
    print(row)

io abbia come risultati
(pippo,13,12,13)
(ciccio,2,1,10)
(nino,4,2,1)
« Ultima modifica: Gennaio 24, 2019, 11:54 da tascio »

Offline nuzzopippo

  • python unicellularis
  • *
  • Post: 38
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #1 il: Gennaio 24, 2019, 13:45 »
...
Come si fa a fare una sorta di self join che mi ritorni un GROUP BY 'nome' con le somme delle colonne.

Ancora non mi sono avventurato nella programmazione dei db con python, è quindi probabile che sia la mia ignoranza a darmi questa perplessità : non puoi interrogare direttamente il database e farti dare i dati già completi?
Esempio in postgresql :
data la tavola :
prova=# select * from totascio;
  nome  | val1 | val2 | val3
--------+------+------+------
 pippo  |    5 |    9 |    2
 ciccio |    2 |    1 |   10
 nino   |    4 |    2 |    1
 pippo  |    2 |    1 |   10
 pippo  |    6 |    2 |    1
(5 righe)

si avrebbe il Tuo risultato così :
prova=# select nome, sum(val1), sum(val2), sum(val3)
from totascio
group by nome;
  nome  | sum | sum | sum
--------+-----+-----+-----
 pippo  |  13 |  12 |  13
 ciccio |   2 |   1 |  10
 nino   |   4 |   2 |   1
(3 righe)

Quindi sarebbe sufficente inviare direttamente una analoga query per avere il risultato e ciclare tra i dati direttamente.

Alternativa sarebbe ciclare i singoli records "puri" ed utilizzare processi decisionali da codice per le somme e memorizzazioni.

Offline tascio

  • python erectus
  • ***
  • Post: 175
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #2 il: Gennaio 25, 2019, 09:21 »
Cercavo proprio questo, seguendo il tuo suggerimento ho fatto
sql = "SELECT nome,Rimarc_Primaria_Gialla,Rimarc_Secondaria_Gialla,Rimarc_Doppia_Gialla,\
SUM(Rimarc_Primaria_Gialla), SUM(Rimarc_Secondaria_Gialla),\
SUM(Rimarc_Doppia_Gialla) FROM allevatore GROUP BY nome"


Funziona, ma mi restituisce anche 3 altri valori che non capisco cosa siano^^

('RUCAT AGRICOLA S', 3, 3, 3, 6, 3, 6)

gli ultimi 3 valori 6,3,6 sono corretti, sono la somma di 3 record con lo stesso nome, ma i primi 3,3,3 non so cosa siano...



Offline nuzzopippo

  • python unicellularis
  • *
  • Post: 38
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #3 il: Gennaio 25, 2019, 11:54 »
...
Funziona, ma mi restituisce anche 3 altri valori che non capisco cosa siano^^
...

Ohmammamia che nomi!

Scherzo (ma solo un po'), ti risponde esattamente ciò che hai chiesto ... se vuoi solo se somme, prova così :
sql = "SELECT nome,SUM(Rimarc_Primaria_Gialla), SUM(Rimarc_Secondaria_Gialla),\
SUM(Rimarc_Doppia_Gialla) FROM allevatore GROUP BY nome"


[Edit] dimenticavo :
I tre valori "strani" sono i campi che Tu hai indicato al di fuori delle somme, in base a quale criterio vengano esposti su due piedi non saprei dire ma li hai chiesti tu.

Faresti bene a studiarti la struttura della tavola che interroghi, per affinare le tue ricerche, i database relazionali seguono regole ben precise (anche se spesso "personalizzate") e capirne il funzionamento, condendo con un po' di SQL ti aiuterebbe.
« Ultima modifica: Gennaio 25, 2019, 12:01 da nuzzopippo »

Offline tascio

  • python erectus
  • ***
  • Post: 175
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #4 il: Gennaio 25, 2019, 12:29 »
Sono un babbo, erano nel select ovviamente... e i valori 3 sono i singoli valori di uno dei record da sommare.
Conosco poco sql per lo più per l'estrazione, join e cose cosi', non sapevo usare la funzione SUM (non la conoscevo) ed era da tanto che non usavo sql... quindi ero in confusione per delle stupidaggini.
Grazie raga ho risolto tutto.

Offline tascio

  • python erectus
  • ***
  • Post: 175
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #5 il: Gennaio 25, 2019, 17:51 »
Altra domanda, è possibile estrarre insieme al valore anche il nome della colonna ed associarlo?
Qualcosa che mi restituisca invece che solo
('RUCAT AGRICOLA S', 6, 3, 6)


anche il nome della colonna
('RUCAT AGRICOLA S', (nomecolonna,6), (nomecolonna,3),(nomecolonna,6))

qualcosa del genere, tipo delle tuple non so...

Offline nuzzopippo

  • python unicellularis
  • *
  • Post: 38
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #6 il: Gennaio 25, 2019, 18:06 »
Rispondi da cellulare.

Si, ė possibile estrarre i nomi dei campi ma bisognerebbe un po' vedere.

Ciò che mi chiedo ė a cosa ti serva, dato che li conosci già (li hai inseriti nella query) basta manipolare il print.

[Edit] ora sono al computer, Su postgresql farei così :
sql = "SELECT nome, 'Maremma : ' || SUM(Rimarc_Primaria_Gialla)::int as test,\
'Bucaiola : ' || SUM(Rimarc_Secondaria_Gialla)::int as test,\
SUM(Rimarc_Doppia_Gialla) FROM allevatore GROUP BY nome"


Appena testata sullo 8-3 in macchina virtuale, purtroppo non posso postarne l'output, ma va ... in altri sistemi db  : manuali! ;)

N.B - corretta la query, avevo mischiato voci mie con quelle di @tascio.
« Ultima modifica: Gennaio 25, 2019, 20:18 da nuzzopippo »

Offline nuzzopippo

  • python unicellularis
  • *
  • Post: 38
  • Punti reputazione: 0
    • Mostra profilo
Re:Somma di alcune colonne
« Risposta #7 il: Febbraio 28, 2019, 16:50 »
I miei saluti.

Anche se un po' prematuramente, ho cominciato a vedere qualcosa dei db in python e quasi immediatamente mi sono imbattuto nella pep 249, "Python Database API Specification 2.0", che definisce le specifiche cui devono attenersi i drivers python per le varie basi dati.

Pur se penso che lo OP abbia ormai risolto la sua ultima domanda (cui ho risposto in maniera scherzosa), nel leggere la docs ho visto un particolare secondo me pertinente con la discussione che penso sia il caso di segnalare, altri apprendisti come me potrebbero giovarsene.

Il "particolare" è che un oggetto "cursor" deve esporre dei dati descrittivi del result-set definito dalla query ... a prima vista, ciò "non sembra" particolarmente indicativo, infatti esso espone una serie di tuple contenenti, tra l'altro, il nome della colonna ovvero la funzione applicata su di una colonna, sotto un esempio relativo alla query di interrogazione di base a questo post :

>>> curr = conn.cursor()
>>> curr.execute("""
SELECT nome, SUM(val1), SUM(val2), SUM(val3)
FROM totascio
GROUP BY nome
""")
>>> c_data = curr.description
>>> c_data
(Column(name='nome', type_code=1043, display_size=None, internal_size=10, precision=None, scale=None, null_ok=None), Column(name='sum', type_code=20, display_size=None, internal_size=8, precision=None, scale=None, null_ok=None), Column(name='sum', type_code=20, display_size=None, internal_size=8, precision=None, scale=None, null_ok=None), Column(name='sum', type_code=20, display_size=None, internal_size=8, precision=None, scale=None, null_ok=None))


vi è però l'istruzione sql "AS" che ci permette di denominare "diversamente" un dato od una aggregazione di dati restituita, supposto di voler denominare le somme delle colonne in esempio quali "somma_1 ... somma_n" potremmo porre la query

>>> curr.execute("""
SELECT nome, SUM(val1) AS somma_1, SUM(val2) AS somma_2, SUM(val3) AS somma_3
FROM totascio
GROUP BY nome
""")


una tale query ci permetterebbe di estrarre la descrizione "come vorremmo" che sia definita, in maniera semplice

>>> tv_data = curr.description
>>> c_name = []
>>> for elem in tv_data:
c_name.append(elem[0])


>>> c_name
['nome', 'somma_1', 'somma_2', 'somma_3']


la qual cosa permetterebbe, appoggiandosi ad una variabile intermedia, p.e. una lista, di definire le "tuple" richieste dallo OP

>>> my_data = []
>>> for row in curr.fetchall():
nome, uno, due, tre = row
r_data = [nome, (c_name[1], uno), (c_name[2], due), (c_name[3], tre)]
my_data.append(r_data)

>>> for elem in my_data:
print(elem)


['pippo', ('somma_1', 13), ('somma_2', 12), ('somma_3', 13)]
['ciccio', ('somma_1', 2), ('somma_2', 1), ('somma_3', 10)]
['nino', ('somma_1', 4), ('somma_2', 2), ('somma_3', 1)]
>>>


... certamente si può far di meglio (agli esperti battere il colpo) ma mi sembra un metodo "pratico" per il risultato voluto, oltre quello di definire manualmente dati che si conoscono già, non credo sia il caso di andarsi ad esaminare il "vocabolario" di un db con metodi specifici.

Personalmente, vedo cursor.description utile per eventuali intestazioni di visualizzazioni tabellari dei dati.