Newsgroup: it.comp.appl.access
Titolo: SQL: compattare le colonne non usate

>>>>  
http://www.bb2002.it
 :)  <<<<<
........... [ al lavoro ] ...........

on 25-04-19, Ammammata supposed :

Si fa prima con 2 una query:
- con la prima compatti
- con la seconda elimini i record che hanno
  uno o più campi Null
     DELETE FattureClienti.*, FattureClienti.Valore
     FROM FattureClienti
     WHERE (FattureClienti.Valore Is Null);
 
     ovvero:
DELETE FattureClienti.*, FattureClienti.Valore, FattureClienti.Data
FROM FattureClienti
WHERE (FattureClienti.Valore Is Null AND FattureClienti.Data Is Null);
 
Bruno

 
 
ni, non sono tanti record uno per colonna, sono tanti campi (max 9) uno per 
colonna
 
ho buttato giù un po' di VBA che fa passare i record e se trova campi vuoti 
"shifta" a sinistra quelli dopo, pulendo l'ultimo
 
funziona, niente da dire: per adesso va bene così, sono comunque pochi 
record per cui anche l'elaborazione passa via in un attimo
 
grazie comunque



faccio un aggiunta a braccio, SENZA aver controllato direttamente l'esito
precisando che, come si vede, NON è nemmeno proponibile in generale
 
0) penso che occorra armeggiare intorno ad una query a campi incrociati
 
1) (lupus in fabula ...)
poichè fai vedere che ci sono codici SENZA "valori di riga"
occorre una query di raggruppamento che estrae SOLO qualli con i valori
(CLAUSOLA HAVING sul conteggio dei valori >0)
da tenere buona per lo scopo
 
2) query a compi incrociati "normale" con il join alla query di sopra
(magari elencando i valori possibili delle colonne nella proprietà query)
 
2a) si presume che in questo caso i valori delle colonne siano da 1 a 9
 
3) si genera una nuova query che ha per origine la query a campi incrociati
e si scrive un campo calcolato siffatto:
StringaOK: nz([1];"") & nz([2];"") & <---> & nz([9];"") 
 
PERO'
i valori in StringaOK sono SENZA spazi intermedi,
quindi "soluzione" non valida se i valori sono più di 9.
In questo caso, volendo riproporre il tutto,
si può pensare di sostituire "" con " "  
ma occorre riuscire ad eliminare le eventuali sequenze interne di spazi
(per quella iniziale e finale c'è TRIM,
forse è possibile con le regular expression ?)


precisazione (dopo riprova con dati similari)
Come detto mi si pone un caso simile:
sintetizzare in una stringa le taglie producibili per un capo di abbigliamento
 
dove le taglie hanno valori alfanumerici
(esempi: da 1 a 5 consecutivi, da 38 a 46 solo taglie pari, xs s m l xl xxl)
e dove i singoli capi hanno uno dei "set" di taglie 
(appunto da 1 a 5, da 38 a 46, letterali)
 
quindi mi ritrovo con un campo codice e un campo taglia
 
Per rendere più simile alla lista presentata (numeri da 1 a 9)
diciamo due campi: codice e numero
 
1)query a campi incrociati CON DEFINIZIONE di tutti i possibili valori
delle colonne nella proprietà "intestazioni colonne"
 
TRANSFORM First(numero) AS PrimoDinumero
SELECT codice
FROM tabellaTaglie
GROUP BY codice
PIVOT numero In (1,2,3,4,5,6,7,8,9);
 
nome della query: qryTaglie
 
2) query che riprende quella di sopra 
con solo il campo calcolato che compone la stringa
 
SELECT codice, IIf(IsNull([1]),"",[1] & " ") & IIf(IsNull([2]),"",[2] & " ") & IIf(IsNull([3]),"",[3] & " ") & IIf(IsNull([4]),"",[4] & " ") & IIf(IsNull([5]),"",[5] & " ") & IIf(IsNull([6]),"",[6] & " ") & IIf(IsNull([7]),"",[7] & " ") & IIf(IsNull([8]),"",[8] & " ") & IIf(IsNull([9]),"",[9] & " ") AS Espr1
FROM qryTaglie;
 
mi sa che con NZ non si riesca a comporre una stringa come quella che si ottiene con IIF (almeno NON in modo diretto)

 si può fare da SQL o mi devo scrivere una routine in VBA?
 
la query la fai dall'ambiente access o sql server? bisogna usare TSQL da 
sql server e non da access per farlo in quanto servono delle funzioni 
tipo row_number etc...che in sql access non sono supportate
 
 

 la query la fai dall'ambiente access o sql server?
 
la query è in SQL server
poi passo i dati ad access dove sistemo la tabella con il vba


 205 1 2 - 4
 
 
ecco il comando per creare quella griglia:
 
TRANSFORM sum(numriga)
SELECT codice
FROM tabella
GROUP BY codice
PIVOT numriga In (1,2,3,4,5);
 

 
 
 
allora puoi usare una CTE , common table expression:
 
WITH cte AS
(
     SELECT *
           ,ROW_NUMBER() OVER(PARTITION BY t.codice ORDER BY t.numriga) 
AS numrigaIndex
     FROM @tbl t
)
SELECT t.codice
       ,MAX(CASE WHEN t.numrigaIndex=1 THEN numriga END) AS [1]
       ,MAX(CASE WHEN t.numrigaIndex=2 THEN numriga END) AS [2]
       ,MAX(CASE WHEN t.numrigaIndex=3 THEN numriga END) AS [3]
       ,MAX(CASE WHEN t.numrigaIndex=4 THEN numriga END) AS [4]
FROM cte t
GROUP BY t.codice;
 
(aggiungi le altre linee fino a quanto ti basta..)
e ottieni il compattamento:
 
codice  1       2       3       4
------------------------------------
201     1       2       NULL    NULL
202     2       NULL    NULL    NULL
203     1       3       NULL    NULL
204     NULL    NULL    NULL    NULL
205     1       2       4       NULL
 
 

prima ho creato la tabella:
 
DECLARE @tbl TABLE(codice INT, numriga INT)
INSERT INTO @tbl VALUES
  (201,1)
,(201,2)
,(202,2)
,(203,1)
,(203,3)
,(204,NULL)
,(205,1)
,(205,2)
,(205,4);

 
 
bella zio ;) grazie per lo spunto
per il momento lascio la cosa divisa in due tra sql e vba ma ho salvato i 
due post nella kb


 205     1       2       4       NULL
 
Ma scusa, cosa ci stanno a fare il 2 sotto l'1,
il 3 sotto il 2, il 4 sotto il 3?
Non sarebbe più corretto rappresentare la
trasformazione così?
 
Codice  1       2       3       4
----------------------------------
201     *       *
202             *
203     *               *
204
205     *       *               *
 
Bruno

 
 
ehm...
 
a me serve appunto che i valori dei 9 campi, spesso inframezzati da null o 
del tutto assenti, vengano appunto "compattati" tutti a sinistra
 
non si tratta di mettere un 3 sotto il 3, quello lo fa già il comando SQL
 
i valori 1-2-3-4... dei "nomi dei campi" sono puramente esemplificativi, 
avrei potuto usare le lettere o i nomi dei 7 nani (più biancaneve e 
grimilde per arrivare a nove)
 
idem per i valori dei campi: 1-2-3-4- sono solo esempi, in realtà sono 
codici agenti e accantonamenti, lunghi da 1 a 4 cifre
