'11/13/03‘ (Continued on next slide)"> '11/13/03‘ (Continued on next slide)">

Presentation is loading. Please wait.

Presentation is loading. Please wait.

DB2 SQL from the Trenches George Smith Metro Midrange Systems Association November 18, 2014.

Similar presentations


Presentation on theme: "DB2 SQL from the Trenches George Smith Metro Midrange Systems Association November 18, 2014."— Presentation transcript:

1 DB2 SQL from the Trenches George Smith Metro Midrange Systems Association November 18, 2014

2 Use of Temporary Data Set With Summary (Item, Created) as (Select ilitm, MIN(JDDCONV(iltrdj)) as CreatedJDDCONV from fotedta.F4111 Where ildct = 'IC' group by ilitm) Select imlitm, imdsc1, created from fotedta.F4101 Join Summary on imitm = item Where imstkt = 'S' and created > '01/01/2011' Order by 3 Here is a simple determination of the first time an item in our inventory was created. The first ‘IC’ record for a product in the Inventory Transaction file can be pulled by applying the “MIN” function to the transaction date. The “With” operation permits the building of a temporary data set to be used for joining to another file and helping to limit or enhance the data being presented.

3 From a response in JDEList for the JDDCONV date conversion used my examples By using three SQL functions you can turn a JD Edwards Julian date into a more usable format. The following SQL statement will give you all of the sales order records from F4211 that have a transaction date greater than today's date: SELECT * FROM F4211 WHERE DATE(DIGITS(DECIMAL(SDTRDJ + 1900000,7,0))) > CURRENT DATE The DECIMAL(SDTRDJ + 1900000,7,0) will turn the internal date into a Julian format of YYYYNNN. The DIGITS function turns the numeric value into a character string. The DATE function will convert the character string into a date data type. The "CURRENT DATE" value will substitute today's date. To specify a date other than today use: SELECT * FROM F4211 WHERE DATE(DIGITS(DECIMAL(SDTRDJ + 1900000,7,0))) > '11/13/03‘ (Continued on next slide)

4 At my current client site I used the following to create a function called JDDCONV in library QGPL: CREATE FUNCTION QGPL/JDDCONV (JDEDATE DECIMAL(6,0)) RETURNS DATE LANGUAGE SQL SET OPTION DATFMT=*ISO BEGIN DECLARE F_OUTPUT DATE ; DECLARE F_TEST INTEGER ; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET F_TEST = 1 ; SET F_TEST = 0; SET F_OUTPUT = DATE(DIGITS(DECIMAL(JDEDATE+1900000,7,0))); IF F_TEST = 0 THEN RETURN F_OUTPUT ; ELSE RETURN NULL; END IF; END I then can change my original SQL statement to: SELECT * FROM F4211 WHERE JDDCONV(SDTRDJ) > CURRENT DATE I hope this helps. Mike Iaconis, President Soar Technology Solutions

5 First Production Date

6 Sell By Date Exceptions Table output using a text member in RUNSQLSTM Create Table QGPL/F58SQL032 as ( With ONHAND (limcu, liitm, lilotn, total ) as (Select limcu, liitm, lilotn, cast(sum(lipqoh) as dec(9,0)) as total From F41021 group by limcu, liitm, lilotn) Select ibmcu, iblitm, imdsc1, iolotn, iolots, jddconv(iobodj) as BasedON, ibsld, jddconv(iommej) as Expire, ibsbdd, jddconv(iosbdj) as Sellby, jddconv(iommej) + IBSBDD days as nwsellby, days(jddconv(iosbdj)) - days((jddconv(iommej) + ibsbdd days)) as daysdiff, total as onhand, ibstkt From F4108 Join F4102 on (iomcu, ioitm) = (ibmcu, ibitm) Join F4101 on imitm = ioitm Join ONHAND on (iomcu, ioitm, iolotn) = (limcu, liitm, lilotn) Where jddconv(iosbdj) <> jddconv(iommej) + IBSBDD days and total <> 0 and imglpt in ('INJU','INSC', 'INST') and ibmcu in (' 130', ' 150') order by 2,1 ) With Data;

7 Sell By Date Exceptions /* ---------------------------------------------------------------- */ /* --------- Build File F58SQL032 --------------------------------- */ /* ---------------------------------------------------------------- */ CHKOBJ OBJ(QGPL/F58SQL032) OBJTYPE(*FILE) /*--------- If exists, delete the file so the SQL can create it. ---*/ MONMSG MSGID(CPF9801) EXEC(GOTO CMDLBL(FILEOK)) DLTF FILE(QGPL/F58SQL032) FILEOK: RUNSQLSTM SRCFILE(*LIBL/FOTESRC) SRCMBR(L58SQL032) + COMMIT(*NONE)

8

9 Shipping Performance Extract Source Member with Several SQL Processes 0001.00 -- Clear output files. 0002.00 Call QCMDEXC ('CLRPFM Dennis1x ', 17.0); 0003.00 Call QCMDEXC ('CLRPFM Dennis2x ', 17.0); 0004.00 Call QCMDEXC ('CLRPFM Dennis3x ', 17.0); 0005.00 Call QCMDEXC ('CLRPFM Dennis4x ', 17.0); 0006.00 Call QCMDEXC ('CLRPFM Dennis5x ', 17.0); 0007.00 Call QCMDEXC ('CLRPFM Dennis7x ', 17.0); 0008.00 Call QCMDEXC ('CLRPFM Dennisship', 17.0); 0009.00 Call QCMDEXC ('CLRPFM Dennisincp', 17.0); 0010.00 Call QCMDEXC ('CLRPFM SHPPERFORM', 17.0);SHPPERFORM 0011.00 Continued on next slide

10 Shipping Performance CL /* ---------------------------------------------------------------- */ /* --------- Build File SHPPERFORM -------------------------------- */ /* ---------------------------------------------------------------- */ OVRPRTF FILE(QSYSPRT) OUTQ(HLDPRT01) HOLD(*YES) + EXPDATE(*DAYS) DAYS(30) RTVOBJD OBJ(SHPPERFORM) OBJTYPE(*FILE) RTNLIB(&FILELIB) OVRDBF FILE(SHPPERFORM) TOFILE(&FILELIB/SHPPERFORM) RUNSQLSTM SRCFILE(FOTESRC/FOTESRC) SRCMBR(L58SQL009) + COMMIT(*NONE) Continued on next slide

11 0012.00 -- Output File DENNIS1X - Orders Shipped Last Week 0013.00 Insert Into Dennis1X 0014.00 With Ship as 0015.00 (Select jmonday, jsunday From Shipweek 0016.00 Where (CURDATE() - 7 days) Between monday and sunday) 0017.00 Select Distinct sddoco, sdaddj From F42119 0018.00 Join Ship on sdaddj Between jmonday and jsunday 0019.00 Where sddcto in ('SO', 'SZ') and sduorg > 0 0020.00 And sdmcu in ' 130' 0021.00 And sdan8 not in (00189152, 00188521, 00000038, 0022.00 00189117, 00187966, 00999999, 0023.00 00188740, 00187806, 00189205, 0024.00 00188720, 00185533, 0025.00 00188673, 00184255, 0026.00 00188629, 00000605) ; 0027.00 Continued on next slide

12 0028.00 -- Output file DENNIS2X - Orders With Count of Dates Shipped During Week 0029.00 Insert Into Dennis2X 0030.00 Select sddoco, count(*) as count From Dennis1x 0031.00 Group by sddoco ; 0032.00 0033.00 -- Output file DENNIS3X Orders Shipped More Than Once During Week 0034.00 Insert Into Dennis3X 0035.00 Select sddoco From Dennis1x 0036.00 Group by sddoco 0037.00 Having count(*) > 1 ; 0038.00 0039.00 -- Output file DENNIS4X Orders that Still Have Open Lines. 0040.00 Insert Into Dennis4X 0041.00 Select Distinct a.sddoco From 0042.00 Dennis2x a Join F4211 b on 0043.00 a.sddoco = b.sddoco; 0044.00 Continued on next slide

13 0045.00 -- Output file DENNIS5 Items on Orders That Still Have Open Lines. 0046.00 Insert Into DENNIS5X 0047.00 Select Distinct b.sdlitm From 0048.00 Dennis2x a Join F4211 b on a.sddoco = b.sddoco 0049.00 Where sdlitm not in ('FT60', 'GST', 'HAND', 'PLTY', 'TXTX‘, 0050.00 'ADV ', 'CNTR', 'DISC', 'DMG', 'TAQA‘) 0051.00 And sdmcu in ' 130’ 0052.00 order by 1; 0053.00 0054.00 -- Add to file DENNIS4X Orders Shipped more than Once During Week. 0055.00 Insert Into Dennis4x 0056.00 Select Distinct a.sddoco From Dennis3x a Where a.sddoco 0057.00 Not in (Select b.sddoco From Dennis4x b ) ; 0058.00 Continued on next slide

14 0059.00 -- Output file DENNIS7X with Orders Shipped Other Weeks. 0060.00 Insert Into Dennis7X 0061.00 With Ship as 0062.00 (Select jmonday, jsunday From shipweek 0063.00 Where (CURDATE() - 7 days) Between monday and sunday) 0064.00 Select Distinct a.sddoco, jddconv(sdaddj) From F42119 a 0065.00 Join Ship on sdaddj Not Between jmonday and jsunday 0066.00 Join Dennis2x b on a.sddoco = b.sddoco 0067.00 Where sddcto in ('SO', 'SZ') and sduorg > 0 and 0068.00 sdaddj <> 0 ; 0069.00 0070.00 -- Add to file DENNIS4X Orders Shipped Other Weeks. 0071.00 Insert Into Dennis4x 0072.00 Select Distinct a.sddoco From Dennis7x a Where a.sddoco 0073.00 Not in (Select b.sddoco From Dennis4x b ) ; 0074.00 Continued on next slide

15 0075.00 -- Load DENNISSHIP Total Number of Orders Shipped. 0076.00 Insert Into Dennisship 0077.00 Select cast(count(*) as dec(8,0)) as Shipped, 0078.00 cast('Sales Orders Shipped:' as Char(30)) as ShipDsc 0079.00 From Dennis2x ; 0080.00 0081.00 -- Load DENNISINCP Total Number of Orders Shipped Incomplete. 0082.00 Insert Into DennisIncp 0083.00 Select cast(count(*) as dec(8,0)) as Incplt, 0084.00 cast('Shipped Incomplete:' as Char(30)) as IncpDsc 0085.00 From Dennis4x ; 0086.00 Continued on next slide

16 0088.00 Insert Into SHPPERFORM 0089.00 Select 'A' as Seq, 0090.00 'Shipping Week: ' as Column1, 0091.00 (' ' || cast(monday as Char(8)) || ' - ' || 0092.00 cast(sunday as Char(8))) as Column2, ' ' as Column3 0093.00 From shipweek 0094.00 Where (CURDATE() - 7 days) Between monday and sunday 0095.00 Union 0096.00 Select 'B' as Seq, 0097.00 Strip(ShipDsc) ||' '|| strip(cast(Shipped as char(8)))) as Column1, 0098.00 (Strip(IncpDsc) ||' '|| strip(cast(Incplt as char(8)))) as Column2, 0099.00 (strip(cast((Incplt/Shipped) * 100 as dec(5,1))) || ' ' || 0100.00 '% Shipped Incomplete') as Column3 0101.00 From Dennisship a Join Dennisincp b 0102.00 on rrn(a) = rrn(b) Where shipped <> 0 0103.00 Union 0104.00 Select 'C', sdlitm, imdsc1, ' ‘ 0105.00 From Dennis5x Join F4101 on sdlitm = imlitm 0106.00 Order by 1,2 ;

17 And the result is a file that can be sent as a.txt file A Shipping Week: 11/03/14 - 11/09/14 B Sales Orders Shipped: 387 Shipped Incomplete: 28 7.2 % Shipped Incomplete C CVS47550 CVS RENEWAL SPF30 ANTI-AGING C W61022 WALG BRONZE SELF TANNING TWNPK C W68301 WALG ST35 REFRESHING ALOE LTN C 82426 TGT SPORT SPF30 TWINPACK

18 Using the SQL Statement in Excel Addin With Summary (sdan8, sdvr01, Month, Year, xxx) as (select sdan8, sdvr01, Trim(char(Month(qgpl.jddconv(sdtrdj)))) as Month, Trim(char(Year(qgpl.jddconv(sdtrdj)))) as Year, count(*) from fotedta.f42119 where trim(sdmcu) = '150' and sddcto in ('SO', 'SZ') and sdtrdj > 113000 and sdaddj <> 0 group by sdan8, sdvr01, Trim(char(Month(qgpl.jddconv(sdtrdj)))), Trim(char(Year(qgpl.jddconv(sdtrdj))))) Select Year, Case When Length(Month) = 1 Then '0' concat Month Else Month End as Month, sdan8, abalph, count(*) as #of_PO from summary join fotedta.f0101 on sdan8 = aban8 group by year, Case When Length(Month) = 1 Then '0' concat Month Else Month End, sdan8, abalph order by 1, 2, 3 Many times I will use the Interactive STRSQL to build and test the concepts. After I have the desired results I can take the statement and copy/paste into the Excel Addin, the Client Access Data Transfer From IBM i, or a 3 rd party product such as Linoma’s Surveyor. Here is a statement to determine the number of Purchase Orders our customers in Canada have been send us by month for the past two years. The qualified Files and Functions (QGPL.JDDCONV) are required when running in a client program that probably doesn’t have a full Library List. I add then to the statement prior to copying it to the clipboard.

19 Open Excel and select Transfer Data from IBM I Enter Library and File name to continue. Library and File must exist but probably do not have to be the primary file of the SQL.

20 Select Properties and on Conversions Tab select Convert CCSID 65535. On SQL Tab change from Data Transfer to native SQL. Use OK.

21 Then select Data Options (this window will validate the Library & File in the earlier panel). In the SQL Select statement window, highlight the existing statement and then paste the copied statement in the window. The statement can be modified if necessary. Select OK and then next panel will have option to run.

22 Results in Excel

23 In Client Access select Transfer Data from IBM i. Select the Properties icon and there will be the same screens for the transfer as in Excel. Then Ok and then select Data Options.

24 The same Change SQL Select Options panel will be presented and can be copy/paste the same as in Excel. Upon return to the transfer panel the PC options will permit extract to Display, HTML, Printer, or File in various formats.

25 Routine to Advance Date to End of Month SELECT Jddconv(MFDRQJ) as DATE, ((Jddconv(MFDRQJ) + 1 Month) - 1 Day) as NEWDATE, MFDRQJ as JDEJulian, Cast(('1' || Substr(Digits(Year((Jddconv(MFDRQJ) + 1 Month) - 1 Day)),9,2) || Substr(Digits( DayOfYear((Jddconv(MFDRQJ) + 1 Month) - 1 Day)),8,3)) as Dec(6,0)) as NEWJUL From F3460 Where Day(Jddconv(MFDRQJ)) = '01' This routine will set a date that is the 1st day of the month to the last day of the month. e. g. 01/01/13 to 01/31/13 Add 1 to the current month and then subtract 1 day. ps. The newjul field in the select takes a " MMDDYY" date field to JDE Julian. Each of the result fields of the Digits operands are 10 digit results. Digits(year(date)) = 0000002013 needs substr(result,9,2) for 13 or substr(result,7,4) for 2013.

26 Result Set from Date SQL DATE NEWDATE JDEDATE NEWJUL 01/01/12 01/31/12 112,001 112,031 02/01/12 02/29/12 112,032 112,060 03/01/12 03/31/12 112,061 112,091 04/01/12 04/30/12 112,092 112,121 05/01/12 05/31/12 112,122 112,152

27 Use of a Sequence in SQL. Create Sequence Create Sequence RENUMBER Start With 10 Increment By 10 No Maxvalue No Cycle Drop Sequence Drop Sequence RENUMBER The Sequence RENUMBER was created in QGPL. - Use in Update: Update Table Set Field = Next Value for RENUMBER Where X = Y -Use during insert : Insert into Table (SerialNbr, Name) values (next value for renumber, 'Bob White-Quayle'), (next value for renumber, 'Billy Doo'), (next value for renumber, 'Jack O''Napes')

28 Remove Duplicate Records Select iesku, Count(*) From itemex Group By iesku Having Count(*) > 1 Select RRN(a) as RRNO, iesku From itemex a Where Exists (Select * From qtemp/dupitems b Where b.iesku = a.iesku Select iesku, Max(RRNO) as maxrrno From qtemp/dupitems2 Group By iesku Delete From itemex b Where RRN(b) In (Select maxrrno From qtemp/dupitems3) 1.Output a list of SKUs that have more than record to a work file. (qtemp/DUPITEMS) 2.Output list of relative record numbers of SKUs that are in the list of duplicate items. (qtemp/DUPITEMS2) 3.Output a list of the highest relative (Last) record numbers from the list of relative record numbers for each SKU. (qtemp/DUPITEMS3) 4.Delete any record whose relative record number is in the list of the highest relative record number for a SKU. 5.Rinse, repeat till all duplicates are deleted. (looking at the counts in the first file will show the number of times the process will need to be repeated) Note: More than a couple of fields to determine duplicate records will make the first select statement unwieldy as all fields will have to be repeated in each select

29 Excerpt from ITJungle Four Hundred Guru – Three Powerful SQL Words Published December 4, 2013 by Ted Holt Consider the following summary query: select d.ItemNumber, sum(d.Quantity) as Qty, sum(d.Quantity * d.Price) as Extended from InvoiceLines as d group by d.ItemNumber order by 1 Here's the result set: ITEMNUMBER QTY EXTENDED A-1 8 88.00 A-3 7 35.00 A-7 7 52.00 B-1 26 51.25 Z-3 2 18.00 Standard stuff, yet very powerful. It beats writing an RPG program to read a file, check for a control break on item number, sum the quantity and extended price, and write the results to some device. Unquestionably, SQL is powerful.

30 Would you like SQL to be a little more powerful? (The correct answer is "Yes!") Look at this query. Notice the next-to-last line, in red. select d.ItemNumber, sum(d.Quantity) as Qty, sum(d.Quantity * d.Price) as Extended from InvoiceLines as d group by d.ItemNumber with rollup order by 1 And here's the result set. Look at the last line. ITEMNUMBER QTY EXTENDED A-1 8 88.00 A-3 7 35.00 A-7 7 52.00 B-1 26 51.25 Z-3 2 18.00 - 50 244.25 Those two powerful words, WITH ROLLUP, were enough to sum up the item groups into grand totals. Notice the first column of the last row. The summary row for all items cannot have an item number, so the item number column is null.

31 Remaining two words: Group By with Rollup And Grouping GROUP BY builds summary totals by item within date. WITH ROLLUP builds date totals and grand totals. Notice the nulls in the rows that were built by the rollup. Today's third powerful word is GROUPING. This powerful function accepts a column name and returns 0 or 1 to indicate whether or not WITH ROLLUP generated a summary row over that column. I think of the zero as false and the 1 as true, even though SQL has no Boolean type.

32 Three Powerful Words by Ted Holt Three Powerful Words by Ted Holt Published December 4, 2013

33 Additional Resources IT Jungle – Four Hundred Guru http://www.itjungle.com/fhg/fhgindex.html Also consider subscribing to the Four Hundred Guru Newsletter.

34 Additional Resources Of course IBM Knowledge Center – DB2 for i SQL Reference http://www- 01.ibm.com/support/knowledgecenter/ssw_ib m_i_71/db2/rbafz.pdf?lang=en-us

35 And Finally Imbed SQL in CL 0057.00 RUNSQL SQL('INSERT INTO F58035 WITH FIRSTGO + 0058.00 AS (SELECT TDAN8 AS TXAN8, + 0059.00 CAST(TDAEXP/100 AS DEC (10,2)) AS TXTAMT, + 0060.00 CAST (TDSTAM/100 AS DEC (8,2)) AS TXXAMT, + 0061.00 TDTXA1 AS TXTXA1, TDEXR1 AS TXEXR1, + 0062.00 TDDOCO AS TXDOCO, TDDCTO AS TXDCTO, + 0063.00 TDKCOO AS TXKCOO, TDSFXO AS TXSFXO, + 0064.00 CAST(TDLNID/1000 AS DEC(6,3)) AS TXLNID, + 0065.00 CXCRDC AS TXCRDC, JDDCONV(TDDGL) AS + 0066.00 TXDGL1, JDDCONV(TDDSVJ) AS TXDSVJ, + 0067.00 JDDCONV(MAX(CXEFT)) AS TXEFT1 FROM F0018 + 0068.00 JOIN F0015LB ON CXEFT <= TDDSVJ WHERE + 0069.00 CXCRDC = ''CAN'' AND TDDGL BETWEEN ' || + 0070.00 &START || ' AND ' || &END || ' AND + 0071.00 JDDCONV(CXEFT) > JDDCONV(TDDSVJ) - 40 + 0072.00 DAYS GROUP BY TDAN8, TDAEXP, TDSTAM, + 0073.00 TDTXA1, TDEXR1, TDDOCO, TDDCTO, TDKCOO, + 0074.00 TDSFXO, TDLNID, CXCRDC, TDDGL, TDDSVJ) + 0075.00 SELECT TXAN8, TXTAMT, TXXAMT, TXTXA1, + 0076.00 TXEXR1, TXDOCO, TXDCTO, TXKCOO, TXSFXO, + 0077.00 TXLNID, TXCRDC, TXDGL1, TXDSVJ, TXEFT1, + 0078.00 B.CXCRRD AS TXCRRD FROM FIRSTGO A JOIN + 0079.00 F0015 B ON TXEFT1 = JDDCONV(B.CXEFT) AND + 0080.00 B.CXCRDC = ''CAN'' ORDER BY TXDOCO') + 0081.00 COMMIT(*NONE)


Download ppt "DB2 SQL from the Trenches George Smith Metro Midrange Systems Association November 18, 2014."

Similar presentations


Ads by Google