In questo articolo elenco alcuni esempi di istruzioni SQL da eseguire su DB2 dell’AS/400.
Clausola HAVING
Permette di fare test sul risultato di una funzione (sommatoria, conteggio, …).
Esempio, estrarre dalla tabella dei movimenti contabili solo i codici dei clienti che quest’anno hanno movimenti in DARE superiore a 50.000 euro:
SELECT clifo, sum(impeu) FROM moaz200f WHERE fclfo ='C' and damov>20110100 and darav='D' GROUP BY clifo HAVING sum(impeu)>50000 ORDER BY clifo
ATTENZIONE: HAVING va indicato dopo GROUP BY e prima di ORDER BY.
… se volessi ordinare il risultato in modo decrescente sarebbe sufficiente assegnare un nome alias alla sommatoria e utilizzarlo nella clausola ORDER BY:
SELECT clifo, sum(impeu) dare FROM moaz200f WHERE fclfo ='C' and damov>20110100 and darav='D' GROUP BY clifo HAVING sum(impeu)>50000 ORDER BY dare desc, clifo
ATTENZIONE: il nome alias “dare” assegnato alla sommatoria non può essere usato nella clausola HAVING
Clausola FETCH
Se volessi solo le prime 10 righe della query precedente si può utilizzare la clausola “FETCH FIRST 10 ROWS ONLY”. Esempio:
SELECT clifo, sum(impeu) dare FROM moaz200f WHERE fclfo ='C' and damov>20110100 and darav='D' GROUP BY clifo HAVING sum(impeu)>50000 ORDER BY dare desc, clifo FETCH FIRST 10 ROWS ONLY
Clausola JOIN: unione tabelle
Permette di unire 2 o più tabelle.
Ad esempio, se nella query precedente voglio estrarre anche la ragione sociale del cliente (oltre al codice) che si trova in un altra tabella, l’istruzione sarà la seguente:
SELECT a.clifo, b.rascl, sum(a.impeu) dare FROM moaz200f a JOIN ancl201l b ON a.clifo=b.cdcli WHERE a.FCLFO ='C' and a.damov>20110100 and a.darav='D' GROUP BY a.clifo, b.rascl HAVING sum(a.impeu)>50000 ORDER BY dare desc, a.clifo
Questa clausola ha anche le varianti LEFT JOIN e RIGHT JOIN i cui significati e utilizzi sono abbastanza chiari.
In pratica, mentre la JOIN normale è una classica INNER JOIN, ovvero estrae solo le righe che hanno corrispondenza in tutte le tabelle coinvolte, la LEFT JOIN è una OUTER JOIN, ovvero estrae anche le righe della tabella di sinistra che non hanno corrispondenza nell’altra tabella (la RIGHT JOIN fa ovviamente il contrario). Esempio:
SELECT a.clifo, b.rascl, sum(a.impeu) dare FROM moaz200f a LEFT JOIN ancl201l b ON a.clifo=b.cdcli WHERE a.FCLFO ='C' and a.damov>20110100 and a.darav='D' GROUP BY a.clifo, b.rascl HAVING sum(a.impeu)>50000 ORDER BY dare desc, a.clifo
in questo caso vengono estratte anche eventuali righe della tabella moaz200f in cui il contenuto del campo codice cliente (a.clifo) non trova corrispondenza nella colonna b.cdcli della tabella ancl201l. Ovviamente questo caso specifico ha poco senso, ma in altri casi può essere utile.
Concatenare campi
Se desidero ottenere un solo campo da due o più campi alfanumerici posso concatenarli usando il doppio pipe: ||.
Considerando sempre il solito esempio potrei volere, oltre alla ragione sociale del cliente, anche la località unita alla provincia in un unico campo:
SELECT a.clifo, b.rascl, TRIM(b.loccl) || ' - ' || b.procl Localita, sum(a.impeu) dare FROM moaz200f a JOIN ancl201l b ON a.clifo=b.cdcli WHERE a.FCLFO ='C' and a.damov>20110100 and a.darav='D' GROUP BY a.clifo, b.rascl, b.loccl, b.procl HAVING sum(a.impeu)>50000 ORDER BY dare desc, a.clifo
in questo caso utilizzo anche la funzione TRIM sul campo LOCCL per eliminare gli spazi non significativi.
Creazione nuova tabella con risultato nella query
A volte può essere utile creare una nuova tabella con la struttura ed il contenuto del risultato di una query ad esempio per poi esportare il file ottenuto in un foglio di calcolo ed inviarlo per e-mail.
Per farlo devo eseguire un istruzione simile alla seguente:
CREATE TABLE mylib/sqltest AS ( SELECT a.clifo, b.rascl, sum(a.impeu) dare FROM moaz200f a JOIN ancl201l b ON a.clifo=b.cdcli WHERE a.FCLFO ='C' and a.damov>20110100 and a.darav='D' GROUP BY a.clifo, b.rascl HAVING sum(a.impeu)>50000 ORDER BY dare desc, a.clifo ) with data
in questo modo l’output della query viene scritto in nuova nuova tabella: SQLTEST nella libreria MYLIB.
ATTENZIONE: se si vuole creare solo la definizione della tabella senza i dati usare with no data
Nell’esempio precedente la colonna risultato della funzione SUM avrà una dimensione molto grossa. Se volessi impostare una dimensione diversa posso utilizzare la funzione DEC(, , ). Esempio:
CREATE TABLE mylib/sqltest AS ( SELECT a.clifo, b.rascl, DEC(sum(a.impeu), 12, 2) dare FROM moaz200f a JOIN ancl201l b ON a.clifo=b.cdcli WHERE a.FCLFO ='C' and a.damov>20110100 and a.darav='D' GROUP BY a.clifo, b.rascl HAVING sum(a.impeu)>50000 ORDER BY dare desc, a.clifo ) with data
in questo caso, il campo della nuova tabella che conterrà il risultato della funzione SUM sarà di 12 numeri di cui 2 decimali.
MAIUSCOLE E MINUSCOLE
Per fare test su un campo alfanumerico che può contenere caratteri sia MAIUSCOLI che minuscoli si può utilizzare la funzione UPPER per trasformare tutto in MAUISCOLO (oppure LOWER per trasformare tutto in minuscolo).
Ad esempio, se voglio estrarre dalla tabella dei clienti tutti quelli residenti a NAPOLI utilizzerò la seguente istruzione:
select * from ancl200f where upper(LOCCL)='NAPOLI'
in questo modo ottengo il risultato desiderato indipendentemente che la località sia stata inserita con lettere maiuscolo o minuscole. Quindi otterrò quelli che contengono NAPOLI o Napoli o napoli o NaPoLi e via dicendo.
CASE: condizionare il valore di una colonna
Tramite l’istruzione CASE è possibile condizionare il valore di una colonna tra quelle selezionate in base al valore di un determinato campo. Trova molte applicazioni nella clausola SELECT ma ci sono casi in cui può essere comodo usarlo anche in WHERE, ORDER BY e via dicendo.
La sintassi è la seguente:
case when then when then … when then else end
Esempi di utilizzo di CASE
Esempio 1:
SELECT cdcli, rascl, CASE WHEN tpiva='E' THEN 'Esente IVA' WHEN tpiva='S' THEN 'IVA in Sospensione' ELSE 'IVA Normale' END AS "Assoggettamento Fiscale" FROM ancl200f ORDER BY cdcli
in questo esempio condiziono il valore della terza colonna in base al contenuto del flag TPIVA: se è “E” la colonna assume il valore “Esente IVA”, se è “S” la colonna assume il valore “ IVA in Sospensione” altrimenti assume il valore “IVA Normale”.
Esempio 2:
SELECT cdcli, rascl, CASE WHEN cdnaz=' ' THEN 'IT - Italia' ELSE a.cdnaz || '- ' || b.desnaz END AS "Nazione" FROM ancl200f a LEFT JOIN tab_naz b on a.cdnaz=b.codnaz ORDER BY cdcli
in questo esempio la terza colonna assume un valore fisso se CDNAZ è blanks, altrimenti ricava il valore concatenando il contenuto di due campi.
Esempio 3:
SELECT cdcsb, CASE WHEN cdnaz=' ' THEN 'IT - Italia' ELSE a.cdnaz || '- ' || b.desnaz END AS "Nazione", DEC(IFNULL(SUM(CASE WHEN annnb=2009 THEN vlcnb END), 0,), 10, 2) as A_2009, DEC(IFNULL(SUM(CASE WHEN annnb=2010 THEN vlcnb END), 0,), 10, 2) as A_2010, DEC(IFNULL(SUM(CASE WHEN annnb=2011 THEN vlcnb END), 0,), 10, 2) as A_2011 FROM bote261l WHERE annnb>=2009 and cdagb='852' and (tpdcb='F' or tpdcb='A') GROUP BY cdcsb ORDER BY cdcsb
questo esempio mostra il valore venduto di alcuni clienti dal 2009 in poi mettendo il valore di ogni anno in orizzontale su colonne diverse ed è molto interessante per vari aspetti.
Innanzitutto il CASE viene inserito all’interno della funzione SUM, per cui, ad esempio nella seconda colonna, viene fatta la sommatoria di VLCNB solo per i record che hanno ANNNB=2009.
Poi viene utilizzata la funzione IFNULL che permette di assegnare un valore di default nel caso il risultato dell’espressione sia NULLO.
Infine, mostra la potenza della combinazione di queste funzioni dell’SQL per mettere in orizzontale risultati di sommatorie che altrimenti sarebbero state in verticale in quanto l’informazione dell’anno nel file è in un solo campo e non già divisa in più campi.
Esempio 4:
SELECT * FROM bote200f WHERE dattb>20110000 and cdagb='XYZ' ORDER BY CASE WHEN dtbob>0 THEN dtbob ELSE dattb END
in questo esempio CASE viene utilizzato nella clausola ORDER BY per modificare l’ordinamento dei record in funzione di valore del campo DTBOB.
Selezione da lista di valori dinamica
Ci sono casi in cui si ha la necessità di selezionare i record di un file in cui il contenuto di un determinato campo faccia parte di una determinata lista dinamica, ovvero che non può essere fissata staticamente all’interno di un’istruzione SQL.
Ad esempio potrei volere l’elenco dei documenti di vendita abbinati ad agenti che hanno un contratto particolare. Siccome la lista di questi agenti può variare in qualunque momento la inserisco in una tabella nella quale ogni record rappresenta un agente che ha questo contratto.
Supponendo che questa tabella si chiami AGE_SPEC l’istruzione che posso utilizzare è la seguente:
SELECT cdagb,dattb,tpdcb,rareb,attnb,cdcfb,vlcnb FROM bote200f JOIN age_spec ON CDAGB=CD_AGE WHERE dattb>20110100 and rgftb<>'N' and atv07=' ' ORDER BY cdagb, dattb, rareb, attnb
in pratica faccio un JOIN dell’archivio da cui estrarre i record con la tabella degli agenti con contratto speciale.
In questo modo però il motore SQL è costretto a caricarsi in memoria un tabella con l’intero JOIN tra le due tabelle per poi fare le selezioni. A volte può offrire prestazioni migliori NON fare il JOIN ed inserire una SELECT nidificata nel WHERE. Esempio:
SELECT cdagb,dattb,tpdcb,rareb,attnb,cdcfb,vlcnb FROM bote200f a WHERE dattb>20110100 and rgftb<>'N' and atv07=' ' and cdagb=(SELECT cd_age FROM age_spec b WHERE b.cd_age=a.cdagb) ORDER BY cdagb, dattb, rareb, attnb
RUNSQLSTM: eseguire più istruzioni SQL
Per elaborare più istruzioni SQL è possibile servirsi del comando RUNSQLSTM.
E’ sufficiente scrivere l’elenco delle istruzioni da eseguire in un membro di un file sorgente e quindi darlo in pasto al comando prima citato. Esempio:
RUNSQLSTM SRCFILE(MIA_LIB/QRPGLESRC) SRCMBR(SQL_02) COMMIT(*NONE) ERRLVL(20)
In questo caso vengono eseguite tutte le istruzioni contenute nel membro SQL_02 del file QRPGLESRC della libreria MIA_LIB.
Note importanti:
- ogni istruzione (statement) deve terminare con un punto e virgola (;)
- I commenti vanno racchiusi tra “/*” e “*/” come nei programmi CL
- se tra le istruzioni c’è anche il DROP di una o più tabelle che potrebbero non esistere conviene utilizza l’opzione ERRLVL(20) nel comando RUNSQLSTM, altrimenti l’esecuzione si interrompe perchè non trova la tabella da “droppare”
Di seguito un esempio di file con l’elenco di istruzioni da dare in pasto a RUNSQLSTM:
/* ============================== Eventuale eliminazione delle tabelle di lavoro ============================== */ drop table paolo/fornitori; drop table paolo/TB_PAG; /* ============================== creazione tabella pagamenti ============================== */ create table paolo/TB_PAG (cdpag char(3) not null with default, depag char(35) not null with default); insert into paolo/TB_PAG select substr(xcdel, 2, 3), substr(xdtab, 1, 35) from anta201l where XCDTB = 'PAG' and ATA32=' ' order by XCDTB, XCDEL; /* ============================== Creazione tabella fornitori. ============================== */ create table paolo/fornitori (cdfor char(6) not null with default, rasfo char(35) not null with default, cdnaz char(3) not null with default, copag char(40) not null with default); insert into paolo/fornitori select cdfor as "Codice", rasfo as "Ragione Sociale", (case when cdnaz=' ' then 'IT ' else CDNAZ end) as "Nazione", (case when copag=' ' then '= = =' else copag||'- '||b.depag end) as "Pagamento" from anfo200f a left join paolo/TB_PAG b on a.copag=b.CDPAG where ata19 = ' ' order by rasfo
A questo punto non mi vengono in mente altri esempi particolari. Se ne avete qualcuno da aggiungere inseritelo nei commenti che può essere utile a tutti


51 comments
Skip to comment form ↓
maurizio
19 July 2012 at 11:37 (UTC 1) Link to this comment
Complimenti !
Paolo Finardi
19 July 2012 at 01:35 (UTC 1) Link to this comment
grazie.
benvenuto
26 September 2012 at 01:41 (UTC 1) Link to this comment
Grazie per il riepilogo: anche se sono abbastanza digiuno di sql, ho creato la tabella che mi serviva!
Paolo Finardi
27 September 2012 at 06:07 (UTC 1) Link to this comment
… si comincia così e poi …
consiglio spassionato, approfondisco SQL perchè è veramente potente!!!!
Domenico
17 October 2012 at 04:29 (UTC 1) Link to this comment
come posso effettuare più join nella stessa query esempio:
Select a.campo, b.campo1, c.campo2 from tab1 as a inner join tab2 as b on a.campo = b.campo inner join tab3 as c on a.campo = c.campo
Dove Sbaglio???
Paolo Finardi
17 October 2012 at 05:31 (UTC 1) Link to this comment
Select a.campo, b.campo1, c.campo2
from tab1 as a
inner join tab2 as b on a.campo = b.campo
inner join tab3 as c on a.campo = c.campo
la tua query è corretta. Ovviamente, avendo legato tutto con “inner join” verranno mostrati solo i record che hanno corrispondenza in tutt’e tre le tabelle. Se invece vuoi tutti i record di tab1 con gli eventuali record di tab2 e tab3 se esistono devi usare “left join”.
Spero di esserti stato d’aiuto
maurizio
17 October 2012 at 05:36 (UTC 1) Link to this comment
Salve, credo che sia solo una distrazione di “digitazione” nome campo. Nell’istruzione originale del sig. Domenico , credo che sia sufficiente correggere l’tultima istruzione, da “as c on a.campo = c.campo” a “as c on a.campo = c.campo2″. Saluti mg
Paolo Finardi
17 October 2012 at 05:45 (UTC 1) Link to this comment
non penso sia una distrazione perchè avrebbe poco senso mostrare 3 colonne con la stessa informazione. Immagino che c.campo2 sia un informazione diversa da a.campo e che quindi il campo di unione di Domenico sia effettivamente c.campo … però sono solo supposizioni
maurizio
17 October 2012 at 06:01 (UTC 1) Link to this comment
Si , in effetti vista in quest’ottica è giusta la sua risposta. Ho frainteso la domanda, pensavo che il problema era la mancata elaborazione dell’istruzione in quanto tale (come se si trattasse di un errore di sintassi) e non di come ottenere il risultato finale. Saluti mg
domenico
17 October 2012 at 06:16 (UTC 1) Link to this comment
quando eseguo la query nell’editor sql di iNavigator (as400) questo mi ritorna l’errore evidenziando inner.
Quini non riesco ad inserire più di due tabelle, volevo sapere se è una limitazione della versione 5.2 oppure devo guardare altro
Grazie
Paolo Finardi
17 October 2012 at 07:31 (UTC 1) Link to this comment
Non ricordo cosa supporta la 5.2. Prova a togliere inner lasciando solo join. Dovrebbe considerarla inner implicitamente.
Domenico
18 October 2012 at 11:14 (UTC 1) Link to this comment
Già fatto mi restituisce questo errore (naturalmente se faccio un singolo join non ci sono problemi)
Stato SQL: 42601
Codice fornitore: -199
Messaggio: [SQL0199] Parola chiave JOIN non prevista. Token validi: FOR WITH FETCH ORDER UNION OPTIMIZE. Causa . . . : Non era prevista la parola chiave JOIN. E’ stato rilevato un errore di sintassi nella parola chiave JOIN. L’elenco parziale dei token validi è FOR WITH FETCH ORDER UNION OPTIMIZE. Questo elenco presuppone che l’istruzione sia corretta fino alla parola chiave imprevista. E’ possibile che l’errore sia precedente nell’istruzione, ma la sintassi dell’istruzione sembrava valida fino a questo punto.Correzione . . . : Verificare l’istruzione SQL nell’area della parola chiave specificata. E’ possibile che manchino i due punti o il delimitatore SQL. SQL richiede parole riservate da delimitare quando vengono utilizzate come nome. Correggere l’istruzione SQL e tentare nuovamente la richiesta.
Processo terminato perché l’istruzione evidenziata non è stata completata con esito positivo.
Paolo Finardi
18 October 2012 at 01:02 (UTC 1) Link to this comment
è come se non vedesse chiusa la prima join.
E’ veramente strano.
Ho provato a eseguire un istruzione simile in V5R1 e funziona tranquillamente, quindi o è un errore di sintassi (io l’istruzione globale non la conosco) oppure hai un problema sul DB, mancanza di PTF o altro.
Hai scritto che la stai eseguendo da iNavigator, so che sembra assurdo ma a volte … hai provato ad eseguirla da STRSQL in 5250?
Domenico
18 October 2012 at 01:34 (UTC 1) Link to this comment
Da “System iNavigator/DataBase/Esegui uno script SQL”, l’unica cosa è che utilizzo il client access 6.1 perchè è la prima cersione dove è possibile installare il componente di accesso ai .net su Sistema operativo windows a 64 bit.
Pensavo che il problema fosse di versione ma ho provato anche con la 5.2 e mi ritorna lo stesso errore.
Non so come uscirne, c’è un modo per farsi aiutare direttamente da quelli di IBM, considerando che paghiamo la manutenzione sia hardware che software???
Grazie
Paolo Finardi
18 October 2012 at 02:07 (UTC 1) Link to this comment
molto strano.
Comunque se hai la manutenzione software puoi assolutamente chiamare IBM al numero verde. Apri la chiamata e poi ti richiamano loro anche perchè se il problema è nelle PTF loro riescono a farti fare i controlli corretti.
Good luck
Claudio
01 November 2012 at 07:50 (UTC 1) Link to this comment
Come si fa a concatenare una clausola where ???
Paolo Finardi
02 November 2012 at 09:01 (UTC 1) Link to this comment
cosa intendi con “concatenare una clausola where” ?
fare la where su colonne concatenate? inserire una sub-query all’interno della where?
Fammi un esempio
Claudio
02 November 2012 at 11:17 (UTC 1) Link to this comment
Concatenare più colonne nella clausola where. ad es.
select colonna1, colonna2 from miatabella where (colonna1 & colonna2=valore da ricercare)
Paolo Finardi
03 November 2012 at 07:59 (UTC 1) Link to this comment
devi fare così
select colonna1, colonna2 from miatabella where colonna1 concat colonna2 = ‘valore da ricercare’
oppure
select colonna1, colonna2 from miatabella where concat(colonna1,colonna2) = ‘valore da ricercare’
Se preferisci, nella prima istruzione, puoi sostituire la funzione concat con il doppio punto esclamativo “!!” però personalmente preferisco il concat perchè più leggibile.
ciao
Claudio
03 November 2012 at 06:09 (UTC 1) Link to this comment
Grazie mille mi sei stato di grande aiuto !!!
Claudio
04 November 2012 at 02:30 (UTC 1) Link to this comment
Ho provato la funzione “concat” però la query mi restituisce l’errore
“LA QUERY SQL SUPERA IL LIMITE DI TEMPO O IL LIMITE DI MEMEORIA SPECIFICATO”
TI SPIEGO IN DETTAGLIO CHE COSA HO BISOGNO
LA MIA TABELLA CONTIENE:
CAMPO1=ANNO
CAMPO2=MESE
CAMPO3=GIORNO
ECC…….
HO BISOGNO DI ESTRAPOLARE I DATI DI UN DETERMINATO PERIODO DI TEMPO.
IO HO FATTO IN QUESTO MODO:
SELECT * MIATABELLA WHERE (CAMPO1 CONCAT CAMPO2 CONCAT CAMPO3)>20121010 AND (CAMPO1 CONCAT CAMPO2 CONCAT CAMPO3)<20121031
Claudio
04 November 2012 at 08:56 (UTC 1) Link to this comment
Ho provato la funzione “concat” però la query mi restituisce l’errore
“LA QUERY SQL SUPERA IL LIMITE DI TEMPO O IL LIMITE DI MEMEORIA SPECIFICATO”
TI SPIEGO IN DETTAGLIO CHE COSA HO BISOGNO
LA MIA TABELLA CONTIENE:
CAMPO1=ANNO
CAMPO2=MESE
CAMPO3=GIORNO
ECC…….
HO BISOGNO DI ESTRAPOLARE I DATI DI UN DETERMINATO PERIODO DI TEMPO.
IO HO FATTO IN QUESTO MODO:
SELECT * MIATABELLA WHERE (CAMPO1 CONCAT CAMPO2 CONCAT CAMPO3)>20121010 AND (CAMPO1 CONCAT CAMPO2 CONCAT CAMPO3)<20121031
Paolo Finardi
05 November 2012 at 08:45 (UTC 1) Link to this comment
l’istruzione dipende dal tipo dei campi (colonne): sono DECIMAL e CHAR?
Caso 1: campi DECIMAL ==> non puoi usare il CONCAT in quel modo perchè ti darebbe errore perchè puoi usarlo solo con campi CHAR, quindi
SELECT * MIATABELLA WHERE ((CAMPO1*10000) + (CAMPO2*100) + CAMPO3) between 20121010 AND 20121031
Caso 2: campi CHAR
SELECT * MIATABELLA WHERE (CAMPO1 CONCAT CAMPO2 CONCAT CAMPO3) between ’20121010′ AND ’20121031′
a occhio direi che i tuoi campi sono numerici e il “SUPERO TEMPO” è probabilmente dovuto al fatto che la query va in errore
Try!
Claudio
06 November 2012 at 02:01 (UTC 1) Link to this comment
Ottimo ha funzionato alla perfezione !!! UN GRANDE GRAZIE
Claudio
03 November 2012 at 08:39 (UTC 1) Link to this comment
Come faccio a fare una funzione di aggregazione settimanale su un campo che contiene le date..
Es. campo A=date, campo B=descrizione articolo, campo C= quantità, campo D=prezzo.
Voglio sapere la quantità totale venduta settimanalmente di un determinato prodotto.
valore che deve restituire la query:
1° settimana quantità totale venduto del prodotto x;
2° settimana quantità totale venduto del prodotto x;
3° settimana quantità totale venduto del prodotto x.
ecc ecc
Paolo Finardi
04 November 2012 at 12:11 (UTC 1) Link to this comment
Interessante!
devi raggruppare usando la funzione WEEK sul campo date (quindi campoA nel tuo esempio).
Esempio:
SELECT
campoB, WEEK(campoA), SUM(campoC), SUM(campoD)
FROM MiaTabella
GROUP BY campoB, WEEK(campoA)
Devi dare però attenzione al tipo del tuo campo data. Mi spiego meglio, l’esempio che t’ho scritto va bene se il tuo campo data è effettivamente di tipo “DATE”,
spesso, però, su AS400 le date vengono registrate in campi numerici (decimal (8, 0) ) che non possono utilizzati dalla funzione WEEK.
In questo caso devi formattare il valore del tuo campo come un vero campo DATE ovvero AAAA-MM-GG.
Quindi, se il campoA è un campo numerico che contiene una data nel formato AAAAMMGG, l’esempio precedente diventa così:
SELECT
campoB,
WEEK( SUBSTR(CHAR(campoA), 1, 4) concat ‘-’ concat
SUBSTR(CHAR(campoA), 5, 2) concat ‘-’ concat
SUBSTR(CHAR(campoA), 7, 2) ) as Settimana,
SUM(campoC), SUM(campoD)
FROM MiaTabella
GROUP BY campoB, WEEK( SUBSTR(CHAR(campoA), 1, 4) concat ‘-’ concat
SUBSTR(CHAR(campoA), 5, 2) concat ‘-’ concat
SUBSTR(CHAR(campoA), 7, 2) )
Spero di essere stato chiaro.
Giusto per completezza, oltre alla funzione WEEK c’è anche la funzione WEEK_ISO che funziona nello stesso modo ma differisce da WEEK per il criterio con cui viene conteggiata la prima settimana dell’anno (e di conseguenza le altre).
Claudio
07 November 2012 at 09:38 (UTC 1) Link to this comment
Ottimo anche questo ha funzionato alla perfezione… Pian piano sto costruendo la mia applicazione…
Claudio
09 November 2012 at 05:58 (UTC 1) Link to this comment
Ho notato che la funzione “WEEk” considera la settimana da domenica a sabato. Non si può modificare Lunedi-Domenica ???
Paolo Finardi
10 November 2012 at 07:26 (UTC 1) Link to this comment
Devi usare la funzione WEEK_ISO. La sinstassi è uguale a WEEK ma considera Lunedì come primo giorno della settimana
Claudio
18 November 2012 at 06:06 (UTC 1) Link to this comment
Se io volessi ottenere in un campo da che giorno a che giorno prendendo in considerazione il risultato di una funzione week_iso. Come andrebbe costruita la query ??
Es. week_iso=1 dal 2/01/2012 al 08/01/2012
week_iso=2 dal 9/01/2012 al 16/01/2012
ecc.
Paolo Finardi
19 November 2012 at 10:33 (UTC 1) Link to this comment
condiderando che WEEK_ISO considera Lunedì come primo giorno della settimana e considera la prima settimana dell’anno quella che contiene il primo giovedì dell’anno …
lascio a te il piacere di trovare la soluzione
ciao
Claudio
21 November 2012 at 03:00 (UTC 1) Link to this comment
Per trovare la soluzione ho pensato che fosse più idoneo utilizzare la funzione “DAYOFWEEK_ISO”.
select ‘Settimana dal ‘ || CAST(CAST((ANNO || ‘-’ || MESE || ‘-’ || GIORNO)AS DATE)-(DAYOFWEEK_ISO(ANNO || ‘-’ || MESE || ‘-’ || GIORNO)) DAY + 1 DAY AS CHAR(12)) || ‘ AL ‘ || CAST(CAST((ANNO || ‘-’ || MESE || ‘-’ || GIORNO)AS DATE) – (DAYOFWEEK_ISO(ANNO || ‘-’ || MESE || ‘-’ || GIORNO)) DAY + 7 DAY AS CHAR(10)) AS SETTIMANA, ECC
OVVIAMENTE POI CI STA IL GROUP BY CON TUTTA LA PAPPARDELLA DI SOPRA
PROF. CHE NE PENSI ????
Paolo Finardi
22 November 2012 at 07:05 (UTC 1) Link to this comment
dico che l’allievo ha superato il maestro, complimenti!!!!
Veramente ottima
Claudio
22 November 2012 at 05:07 (UTC 1) Link to this comment
Grazie del complimento. Ma il maestro rimane sempre il maestro !!!
Claudio
06 November 2012 at 11:06 (UTC 1) Link to this comment
Come faccio a sapere in quale tabella dell’as400 risiedono i dati che mi occorrono.
Es. Attraverso un terminale 5250 visualizzo i dati di un articolo, come faccio a sapere in quale tabella estrapola quei dati.
Paolo Finardi
07 November 2012 at 08:39 (UTC 1) Link to this comment
mi sa che tu e l’AS non siete amici da molto tempo
da 5250 fai “richiesta sistema” (da PC fai SHIFT+ESC), appare una linea in fondo allo schermo, scrivi “3″ sulla linea e dai “Invio”. Poi scegli l’opzione 14 e dai Invio. A questo punto vedi tutte le tabelle aperte dall’applicazione che stai vedendo sul 5250.
Claudio
07 November 2012 at 09:36 (UTC 1) Link to this comment
Da poco che sto utilizzando questo gestionale, inoltre girando su internet non ho trovato un granchè come documentazione…
Ti ringrazio vivamente per il tuo supporto mi sei veramente di grande aiuto.
Paolo Finardi
08 November 2012 at 06:59 (UTC 1) Link to this comment
Di niente
Claudio
08 November 2012 at 05:49 (UTC 1) Link to this comment
Oggi ho provato il tuo suggerimento e sono rimasto sorpreso del numero di tabelle che va aprire quando chiedo dell’informazioni tramite il’5250.
Claudio
09 November 2012 at 06:29 (UTC 1) Link to this comment
Come faccio a vedere il contenuto di una tabella oppure ad eseguire una query dal terminale 5250 ???
Paolo Finardi
10 November 2012 at 07:27 (UTC 1) Link to this comment
da 5250 esegui il comando STRSQL
a quel punto puoi eseguire tutte le query SQL che vuoi.
Quando hai finito esci col tasto funzionale F3.
Claudio
12 November 2012 at 08:35 (UTC 1) Link to this comment
Dove devo scrivere il comando “STRSQL” ???
Una volta che accedo con la mia username e la password mi ritrovo dentro al menu del punto vendita.
Claudio
13 November 2012 at 10:17 (UTC 1) Link to this comment
Ok risolto !!! Premendo il pulsante ‘ESC’.
Claudio
24 November 2012 at 08:45 (UTC 1) Link to this comment
In alcune tabelle quando utilizzo la clausola where per filtrare uno di questi tre campi (anno, mese o giorno) ci impiega molto tempo per resituirmi il il risultato di una query a differenza di altri campi in cui il tempo di attesa è minimo.
Per quale motivo ??? Grazie
Paolo Finardi
25 November 2012 at 09:30 (UTC 1) Link to this comment
difficile darti una risposta senza avere altre informazioni, potrebbe essere che quei campi non sono in chiave, quindi le prestazioni ne risentono moltissimo.
I filtri sui campo che sono in chiave sono nettamente più veloci.
Claudio
27 November 2012 at 11:00 (UTC 1) Link to this comment
Siccome la mia tabella sta in ordine di data e io avrei bisogno di estrapolare solo le ultime righe che riguardano la giornata odierna.
Ci sta una funzione che mi da la possibilità di estrapolare un certo numero di righe dalla fine???
Sui tuoi esempi ho visto la funzione “FETCH FIRST 10 ROWS ONLY” (indubbiamente rende la mia query più veloce), l’ho utilizzata con un ordine decrescente di data però nel momento che utilizzo ‘order by’ nella mia stringa sql mi restituisce l’errore “LA QUERY SQL SUPERA IL LIMITE DI TEMPO O IL LIMITE DI MEMEORIA SPECIFICATO”.
Mica dipende dal fatto che sto eseguendo la query su una vista logica e non sul file fisico ???
Claudio
21 April 2013 at 08:21 (UTC 1) Link to this comment
Come faccio a selezionare i campi presenti in una stampa ???
Paolo Finardi
22 April 2013 at 06:25 (UTC 1) Link to this comment
in che senso?
Claudio
22 April 2013 at 06:12 (UTC 1) Link to this comment
Es. Quando eseguo degli spostamenti della merce nel magazzino dal terminale 5250 mi lancia una stampa in cui è inidicato la posizione d’origine e quella di destinazione e altre informazioni. Se io volessi modificare il layout di stampa, magari aggiungendo altre informazioni come devo fare ???
Paolo Finardi
23 April 2013 at 06:12 (UTC 1) Link to this comment
è tutta un’altra storia con cui SQL non c’entra niente.
La stampa sarà generata da un programma RPG (in quel caso devi modificare quello) o da un query realizzato con un tool chiamato Query/400. In quel caso devi modificare la definizione del query con il comando WRKQRY (devi però conoscere il nome del query da modificare).
Claudio
23 April 2013 at 06:25 (UTC 1) Link to this comment
Grazie mille. Ma come faccio a sapere se la stampa è generata dal RPG oppure dal tool Query/400 ???