LNAME | UNITS |
A | 1 |
B | 4 |
B | 5 |
C | 6 |
D | 7 |
A | 3 |
A | 5 |
B | 1 |
Expected result:
LNAME | COUNT(*) |
A | 3 |
B | 3 |
I suggested using the table expression (temporary table) method as one of possible solutions for V4R5 and later OS/400 versions:
(Select Lname, count(*) Rowcount From EMP
Group by Lname)
SELECT Lname,count(*) from EMP Group by Lname
Having count(*)=(select max(Rowcount) from XT)
Recently, this response attracted some attention and caused new questions about how and where it could be used.
Table expressions consist of nested table expressions and common table expressions.
Common table expressions can be used to store SELECT statements in an intermediate result table. They can be specified prior to main select in SELECT, INSERT, or CREATE VIEW statements. Table expressions can be helpful when the same result table needs to be shared in a main select.
Table expressions are preceded with the keyword WITH. Keyword AS specifies select for temporary table.
Here's another example: Suppose you have to clear the files in the XFLES library, and those files have not been used for three or more years. The file names all start with AP, AR, or GL.
You can use table expressions to save complicated selection and date manipulation.
In following example, OD is the outfile for the DSPOBJD command, and DUMMY is a one-record dummy file to get system directive and ALBR file (LIB, FIL 10 byte character fields). RUNSQLSTM puts data from the OD file into n ALBR file. The program reads that file and clears the selected files.
DCLF ALBR
DLTF QTEMP/OD
.........................
CLRPFM *LIBL/ALBR
.............................
DSPOBJD OBJ(XFLES/*ALL) OBJTYPE(*FILE) +
OUTPUT(*OUTFILE) OUTFILE(QTEMP/OD)
/* Extract file names */
RUNSQLSTM SRCFILE(yourLIB/QCLSRC) SRCMBR(ABC) +
COMMIT(*NONE)
READ: RCVF
.................
...............
CLRPFM &LIB/&FIL
.....................
GOTO READ
EOJ: ENDPGM
A source file of SQL statement is in YourLIB/QCLSRC ABC member type SQL:
WITH AT AS(
SELECT ODLBNM, ODOBNM,
CHAR(CASE WHEN ODUCEN='0' THEN '19'
WHEN ODUCEN='1' THEN '20' END)|| convert
SUBSTR(ODUDAT ,5,2) ||SUBSTR(CHAR(ODUDAT),1,4) LSTDAT to ccyymmdd
FROM OD
WHERE ODOBAT='PF' AND ODUCEN<>' ' AND
SUBSTR(ODOBNM,1,2) IN ('AP', 'AR', 'GL'))
SELECT DISTINCT ODLBNM, ODOBNM
FROM AT
WHERE LSTDAT< (SELECT
SUBSTR((CHAR(CAST(SUBSTR(CHAR(CURRENT TIMESTAMP),1,4) current date
AS INTEGER)-3)),1,4)||SUBSTR(CHAR((CURRENT TIMESTAMP)),6,2)|| subtract
SUBSTR(CHAR((CURRENT TIMESTAMP)),9,2) CDAT 3 years
FROM DUMMY)
If you got lost in date arithmetic as I did, don't worry. This is certainly not the best solution--even thought it works. The SQL statement--as well as the CL program--could be simplified. This is only an example of how to use temporary tables in RUNSQLSTM.
The same statement could be used as a QM Query.
By the way, if you don't want use temporary tables or MAX(...), just run the following:
From emp a
Group by a.Lname
Having count(*)>=ALL
(select count(*) from emp b Group by b.Lname)
--Issak Brender
LATEST COMMENTS
MC Press Online