lunedì, 20 Gennaio 2025

[mysql] Creare tabella pivot dinamica in MySQL (per esordienti totali)

Con il MySQL è possibile generare tabelle pivot dinamiche, ovvero che contengano nomi di colonne automatiche, in base ad una tabella di riferimento.

Quello che vogliamo ottenere sarà un risultato come il seguente:

Prima di cominciare creiamo un database con un po’ di dati in modo da poterci lavorare.

1. Creazione dati di partenza

Creiamo 3 tabelle: prodotti, agenti e vendite. Di seguito riporto le query per creare le singole tabelle ed inserire i dati di esempio.

PRODOTTI

Per creare la tabella prodotti eseguiamo la seguente query.

Inseriamo i dati nel modo seguente:

AGENTI

Andiamo adesso a creare la tabella degli agenti, in modo analogo:

Ed inseriamo i dati:

VENDITE

Per le vendite andremo a creare la tabella in questo modo:

A differenza delle precedenti due, qui voglio inserire dei dati casuali. Per inserire una riga di dati casuali, pescati dalle precedenti due tabelle, potremmo scrivere:

Faccio notare che con l’istruzione ROUND(1+RAND()*4,0) inseriamo un valore intero casuale tra 1 e 5. Se volessimo generalizzare il procedimento potremmo scrivere ROUND(n+RAND()*(m-n),0) dove n è il minimo, mentre m è il massimo.

Con n = 3 e m = 8 avremmo infatti le seguenti operazioni:

  1. RAND() genera un valore casuale decimale da 0 a 1
  2. Moltiplicando per (8-3) il valore casuale sarà tra 0 e 5.
  3. Sommano il risultato a 3 il valore casuale sarà un decimale tra 3 e 8. Potrebbe essere per esempio 6,4.
  4. Usando ROUND() arrotondiamo a 0 cifre decimali ottenendo quindi un intero.

Se volessimo inserire più di una riga in una singola operazione, possiamo farlo scrivendo una procedura.

Dichiariamo quindi una procedura nel modo seguente, che inserisca 1000 valore casuali per volta.

Chiamiamo la procedura digitando:

2. Creazione tabella pivot

Per creare una tabella pivot manualmente utilizziamo CASE WHEN ... END. A mano potremmo scrivere una query come quella di seguito:

Ogni colonna della pivot sarà generata da:

In questo caso noi abbiamo una tabella dei prodotti, dove sappiamo esserci all’id = 1 il prodotto chiamato mele.

Con SUM() sommiamo i valori (avremmo potuto usare COUNT(), AVG(), MAX(), MIN() ecc.) e con ROUND() arrotondiamo. Quest’ultima funzione in particolare non sarebbe necessaria, ma la utilizzo solo perché, visto che si parla di importi in euro, non ha senso calcolare un risultato al di sotto dei centesimi.

Quello che vogliamo fare ora è poter scrivere, quel pezzo di query, in modo iterativo, ripetendola per CIASCUN valore della tabella prodotti.

In particolare potremmo eseguire una query come la seguente:

Il risultato di questa query sarebbe un singolo campo contenente i seguenti valori:

Faccio notare che grazie a GROUP_CONCAT() vengono inserite le virgole tra le singole righe.

Andiamo a creare quindi una procedura come la seguente:

Eseguiamo, come prima, la procedura:

Otterremo il risultato cercato.

Dobbiamo usare una procedura per evitare di incorrere in una serie di incongruenze legate all’interrogazione del database.

DIfatti, usando il PHPMyAdmin e lanciando solamente l’istruzione:

Si incorrere nel seguente errore:

Fatal error: Uncaught Error: Call to a member function getClauses() on null in D:\xampp\phpMyAdmin\vendor\phpmyadmin\sql-parser\src\Utils\Query.php:564 Stack trace: #0 D:\xampp\phpMyAdmin\vendor\phpmyadmin\sql-parser\src\Utils\Query.php(681): PhpMyAdmin\SqlParser\Utils\Query::getClause(NULL, NULL, 'ORDER BY', -1, false) #1 D:\xampp\phpMyAdmin\libraries\DisplayResults.php(1385): PhpMyAdmin\SqlParser\Utils\Query::replaceClause(NULL, NULL, 'ORDER BY', '') #2 D:\xampp\phpMyAdmin\libraries\DisplayResults.php(4376): PMA\libraries\DisplayResults->_getUnsortedSqlAndSortByKeyDropDown(Array, '') #3 D:\xampp\phpMyAdmin\libraries\sql.lib.php(1689): PMA\libraries\DisplayResults->getTable(Object(mysqli_result), Array, Array, false) #4 D:\xampp\phpMyAdmin\libraries\sql.lib.php(1980): PMA_getHtmlForSqlQueryResultsTable(Object(PMA\libraries\DisplayResults), './themes/pmahom...', NULL, Array, false, 6, 6, NULL, Object(mysqli_result), Array) #5 D:\xampp\phpMyAdmin\libraries\sql.lib.php(2199): PMA_getQueryResponseForResultsReturned(Object(my in D:\xampp\phpMyAdmin\vendor\phpmyadmin\sql-parser\src\Utils\Query.php on line 564

3. Utilizzo della tabella nel PHP

Leggiamo la tabella tramite il PHP. Per farlo utilizzerò la classe MySQLdb come in questo esercizio sul MySQL Cluster.

Creiamo nella root del nostro sito un file MySQLdb.php contenente il seguente codice:

Creiamo adesso un file index.php, nella stessa posizione, contenente il seguente codice:

Vediamo in particolare come nel vettore $prodotti abbiamo l’elenco di tutti i prodotti e quindi delle colonne della pivot, che si trovano in $dati. Il risultato che otterremo sarà simile a questo:

 

Google Drive, upload bloccato su “meno di un minuto rimanente”

Problema: quando si cerca di caricare su Google Drive un documento di dimensioni consistenti (nel mio caso il problema si presentava con file di appena qualche MB) l’upload non riesce ad andare a buon fine e si blocca su un caricamento simile a quello nell’immagine, dando per tempo stimato “Meno di un minuto rimanente”

Soluzione: il problema può dipendere da Kaspersky Internet Security. Dalle Impostazioni di rete disattivare Scansione delle connessioni crittografate.

Più nel dettaglio ho notato che questo problema affligge tutti gli upload via web. Anche tentando il caricamento altrove, non solo su Google Drive, ed utilizzando qualsiasi browser (ho trovato indistintamente il medesimo problema sia su Chrome, Firefox che Edge).

In generale il problema si presenta come l’impossibilità di stimare il tempo di upload necessario, per cui qualunque barra di upload arriva subito alla fine e si blocca lì fino al completamente del medesimo.

Il problema dipende da Kaspersky Internet Security, nel mio caso ho verificato il problema sulla versione 20.0.14.1085 (j) con Windows 10 x64 Build 18362.

Per risolvere il problema aprire Kaspersky Internet Security > Impostazioni > Avanzate > Rete (Impostazioni di rete) > Scansione delle connessioni crittografate

Selezionare Non esaminare le connessioni crittografate.

Come utilizzare su Linux l’SFTP per trasferire e gestire i file da riga di commando

L’SFTP (SSH File Transfer Protocol) è un protocollo simile al FTP, utilizzato però per trasferire e manipolare file mediante SSH.

I comandi utilizzati sono simili a quelli del FTP. E’ molto utile specialmente quando si devono trasferire i file da un server all’altro.

1. Collegarsi in SFTP

Per collegarci al server remoto in SFTP digitiamo:

Per collegarci al server remoto su una porta diversa dalla 22

Una volta collegati ci verrà richiesta la password.

2. Comandi disponibili in SFTP

Per ottenere l’elenco di tutti i comandi disponibili, digitiamo:

L’output sarà simile al seguente:

bye Quit sftp
cd path Change remote directory to ‘path’
chgrp grp path Change group of file ‘path’ to ‘grp’
chmod mode path Change permissions of file ‘path’ to ‘mode’
chown own path Change owner of file ‘path’ to ‘own’
df [-hi] [path] Display statistics for current directory or filesystem containing ‘path’
exit Quit sftp
get [-Ppr] remote [local] Download file
reget remote [local] Resume download file
help Display this help text
lcd path Change local directory to ‘path’
lls [ls-options [path]] Display local directory listing
lmkdir path Create local directory
ln [-s] oldpath newpath Link remote file (-s for symlink)
lpwd Print local working directory
ls [-1afhlnrSt] [path] Display remote directory listing
lumask umask Set local umask to ‘umask’
mkdir path Create remote directory
progress Toggle display of progress meter
put [-Ppr] local [remote] Upload file
pwd Display remote working directory
quit Quit sftp
rename oldpath newpath Rename remote file
rm path Delete remote file
rmdir path Remove remote directory
symlink oldpath newpath Symlink remote file
version Show SFTP version
!command Execute ‘command’ in local shell
! Escape to local shell
? Synonym for help

3. Scaricare file e cartelle dal SFTP

Per scaricare un singolo file, nella posizione nella quale abbiamo aperto l’SFTP, digitiamo:

Per scaricare un file rinominandolo oppure scaricandolo in una posizione locale diversa:

Per scaricare una cartella digitiamo:

Per scaricare tutti i file della cartella corrente remota nella cartella locale attuale:

4. Caricare file e cartelle sul SFTP

Per caricare un file locale nella posizione remota, digitiamo:

Per caricare una cartella locale sul server remoto digitiamo:

Per caricare tutti i file della cartella locale sul server remoto:

5. Manipolare file e cartelle sul SFTP

Vedere tutto il contenuto di una cartella:

Creare una cartella:

Rinominare un file:

Rimuovere un file:

Rimuovere una cartella:

[vba] Classe per leggere e scrivere su un database MySQL

A seguito del precedente articolo [excel] Aggiungere all’origine dati delle tabelle da un database MySQL ho deciso di integrare l’esercizio creando una classe per leggere e scrivere tramite VBA su un database MySQL.

Affinché la classe funzioni ricordiamoci di installare il connettore recuperabile sul sito ufficiale (Connector/ODBC 8.0.19). Inoltre ricordiamoci anche che per poter eseguire la connessione ADO abbiamo bisogno di importare l’opportuna libreria dai riferimenti. In questo modo:

Detto tutto questo possiamo creare una classe MySQL con le seguenti istruzioni all’interno:

Possiamo usare la classe nel modo seguente:

Faccio notare che con il metodo clear possiamo aggiungere gli slash agli apici, presenti nel cognome.

[excel] Aggiungere all’origine dati delle tabelle da un database MySQL

Vediamo come collegare su Excel una tabella da un database MySQL. Per il mio esempio utilizzerò un database MySQL installato in locale grazie a XAMPP.

Chiameremo il database in questione torregatti e lo struttureremo nel modo seguente, con due tabelle: clienti e agenti

Il file di creazione del database si trova al seguente link: torregatti.zip

A questo punto dobbiamo procurarci l’opportuno Driver ODBC, se non lo abbiamo già installato. In particolare per il MySQL il driver è recuperabile sul sito ufficiale (Connector/ODBC 8.0.19).

Una volta installato e scaricato andiamo a verificare la stringa di connessione.

Premiamo il tasto WIN + R. Nella finestra Esegui digitiamo %systemdrive%\Windows\SysWoW64\odbcad32

In questo modo apriremo l’Amministrazione origine dati ODBC (32 bit). Nel caso si debba aprire quella a 64 bit sarà sufficiente digitare odbcad32 oppure %systemdrive%\Windows\System32\odbcad32

Nella scheda Driver individuiamo il driver che ci interessa, in questo modo:

Nel mio caso è il MySQL ODBC 8.0 ANSI Driver

Fatto questo apriamo Excel e andiamo Dati > Recupera dati > Da altre origini > Da ODBC

Nella finestra Da ODBC selezioniamo Nome origine dati (DNS) come Nessuno e apriamo le Opzioni avanzate. Alla Stringa di connessione inseriamo la seguente stringa: DRIVER={MySQL ODBC 8.0 ANSI Driver};SERVER=localhost;

Qualora il nostro database non si trovasse in locale sostituiamo localhost con l’indirizzo del database. Fatto tutto questo premiamo su OK. A questo punto, se è la prima volta che effettuiamo la connessione, ci verranno chiesto nome utente e password. Selezionare la voce Database e scegliere come username root e lasciare il campo password vuoto. Queste impostazioni dipendono, nel mio caso, dal fatto che sto utilizzando XAMPP. In altre circostanze dovrò inserire nome utente e password appropriati.

Fatto questo possiamo selezionare la tabella alla quale ci vogliamo connettere.

Nel mio caso voglio prelevare la tabella agenti:

Una volta selezionata la tabella che ci interessa premere su Carica.

Possiamo caricare anche delle viste in MySQL, come nel mio caso la vista clienti_agenti. Se tutto è andato bene vedremo un risultato simile a questo:

[VBA] Tema musicale di Tetris eseguito da una macro in VBA su Excel

Ispirato da un articolo che ho trovato online sull’argomento (Tetris Theme Song Using Processing) ho deciso di riprodurre il medesimo risultato in VBA su Excel, riproducendo quindi il tema musicale di Tetris tramite una macro per Excel.

Anzitutto importiamo dal kernel32 di Windows la funzione appropriata per eseguire un Beep, riproducendo quindi un suono, nel modo seguente:

La funzione accetta due argomenti: frequenza in Hz e durata in ms. Quindi per eseguire un 1 beep a 800Hz di 0,5 secondi, dovremo scrivere: Beep 800, 500

Detto questo voglio anzitutto riconvertire le funzioni dell’esempio nel link in VBA, creando un vettore di frequenze ed uno dei tempi, nel modo seguente:

Faccio notare che per la conversione dello spartito (che si può trovare al seguente link) è stata usata una tabella di conversione simile a questa.

Detto questo voglio riportare la medesima tabella di conversione in Excel, in un foglio che chiameremo NOTE. Il risultato che otterremo sarà simile a questo:

A questo punto voglio creare un altro foglio, chiamato SPARTITO, dove creeremo tre colonne, una nella quale scegliere le note e l’altra dove inserire i tempi come ottavi di nota.

A questo punto associamo al pulsante Suona la seguente macro:

Le frequenze vengono recuperate dal foglio NOTE.

Da qui si può scaricare il file excel comprensivo di macro: excel VBA – note musicali – tema tetris

Impostazione percorso della metropolitana in Resident Evil 3 Remake

Per risolvere l’enigma della metropolitana, in Resident Evil 3 Remake, bisogna anzitutto riattivare la corrente elettrica (questo passaggio è abbastanza semplice, basta abbattere i ragni che infestano la centrale elettrica).

Una volta riattivati i generatori per l’energia elettrica della centrale, possiamo tornare alla sala di controllo della metropolitana di Raccoon City. Qui dovremo impostare il percorso, seguendo la mappa delle stazioni possibili. La combinazione corretta è quella dell’immagine di seguito:

La combinazione in particolare è: FA 02 – RA 03 – SA 02 – FO 01

Le sigle rappresentano le iniziali delle varie stazioni sul percorso. Una volta attivate correttamente verrà data conferma del percorso sul pannello di controllo frontale.

Combinazione casseforti in Resident Evil 2 Remake [Leon 2nd run]

1. Ufficio ovest della Stazione di Polizia, primo piano: sinistra 9, destra 15, sinistra 7

2. Sala d’attesa al secondo piano della Stazione di Polizia: sinistra 6, destra 2, sinistra 11

3. Sala di trattamento delle fogne: sinistra 2, destra 12, sinistra 8

Combinazioni dei lucchetti in Resident Evil 2 Remake [Leon 2nd run]

1. Secondo piano Stazione di Polizia: armadietti spogliatoio delle docce – combinazione CAP

2. Terzo piano Stazione di Polizia: armadietto in fondo al corridoio – combinazione DCM

3. Ufficio Ovest, scrivania di Leon: a sinistra NED e a destra MRG

4. Stanza di Controllo nelle fognature – combinazione SZF