fhg
Volume 7, Number 23 -- June 20, 2007

Conditional Counting with Open Query File

Published: June 20, 2007

Hey, Ted:

Is there a way to make Open Query File (OPNQRYF) count records that meet certain criteria? I want to write a summary query, using OPNQRYF, that counts all records, and that also counts only the records that have a positive value in one of the numeric fields. Can OPNQRYF do anything like that?

--Dave


When I got Dave's question, I told him that I thought it could be done, but I'd have to play with it to figure it out. A little while later, Dave had his query and I had another technique to share with you.

It would be nice if OPNQRYF had an %IF function to carry out conditional calculations. However, I seriously doubt IBM will ever add such a function. (Then again, I was wrong about CL.) So, we're back to tricks again, which is not the way I like to write programs.

To illustrate the technique Dave implemented, let's assume an input file that has an association ID field, ASSNID. Dave wants a full count of the file and a count of all records where ASSNID is greater than zero.

Since Dave is running a summary query, he needs a pattern file that contains the layout of the record that OPNQRYF is to build. This file contains no data, and does not even have to have a member. Let's call it WORK.

A          R REC                 
A            FULLCOUNT      5P 0 
A            ASSNCOUNT      5P 0 

Dave has some data to count. Let's call it DATA.

KEY    ASSNID
===    ======
  1       24  
  2       31  
  3        0  
  4        1- 
  5        2- 
  6        3  
  7        2  
  8        0  
  9        1  
 10        5  

Here's the OPNQRYF he used to count his records.

opnqryf file((DATA)) format(WORK) +                             
mapfld((FullCount '%count') +                                   
       (Assn1     '%max(AssnID 0)') +                           
       (Assn2     'Assn1 / %max(AssnID 0.1)') +                 
       (AssnCount '%sum(Assn2)'))                               
cpyfrmqryf data tofile(qtemp/wrk) crtfile(*yes) mbropt(*replace)
clof data                                                       

FULLCOUNT is straightforward. It uses the %COUNT function to count all the records. Let's look at how ASSNCOUNT is loaded. First, work field ASSN1 is assigned the larger of two values--ASSNID and zero. If ASSNID is negative, ASSN1 becomes zero. Otherwise ASSN1 takes the value of ASSNID. Next ASSN2 is calculated as ASSN1 divided by the larger of ASSNID and one-tenth. If ASSNID is positive, ASSN2 is ASSN1 divided by ASSNID, which yields the value one. If ASSNID is negative or zero, ASSN2 takes the value zero divided by one-tenth, which is zero. ASSNCOUNT adds up these ones and zeros. I know that's not intuitive, so you may want to work through a positive, negative, and zero ASSNID.

Here is an example of what Dave would get from the data set given above.

FULLCOUNT  ASSNCOUNT
      10          6 

Dave's question got me to wondering about the feasibility of this technique. It's purely academic interest. Suppose his file also had a one-character CODE field, and I wanted to count the records that had a code A. First, I would need to add a counter field for the code A records to the work file.

A          R REC                 
A            FULLCOUNT      5P 0 
A            ASSNCOUNT      5P 0 
A            COUNTA         5P 0

And there would need to be a code field in the data.

KEY   CODE  ASSNID 
===   ====  ======
  1    A       24  
  2    B       31  
  3    A        0  
  4    A        1- 
  5    C        2- 
  6    A        3  
  7    B        2  
  8    D        0  
  9    D        1  
 10    D        5  

Here's what I came up.

opnqryf file((DATA)) format(WORK) +
mapfld((FullCount '%count') +      
       (Assn1     '%max(AssnID 0)') + 
       (Assn2     'Assn1 / %max(AssnID 0.1)') + 
       (AssnCount '%sum(Assn2)') +              
       (A1        '%or(%xor(%min(%xor(Code ''A'') X''01'') x''01'' ) 
                     x''F0'')' + *char 1) +                          
       (A1d       'A1' *dec 1) +                                     
       (CountA    '%sum(A1d)'))                                      
cpyfrmqryf data tofile(qtemp/wrk) crtfile(*yes) mbropt(*replace)    
clof data                                                           

A1 uses logical functions to create a one or zero, depending on the value of CODE. To understand how it works, work from the inside out. Here's the case when CODE is A.

Expression        Binary
==============    =========
Code              1100 0001
A                 1100 0001
XOR               0000 0000
X'01'             0000 0001
MIN               0000 0000
X'01'             0000 0001
XOR               0000 0001
X'F0'             1111 0000
OR                1111 0001

Binary 11110001 is hexadecimal F1, which is the character 1. All records that have a code of A generate a one.

Here's how the expression works when code is B.

Expression        Binary
==============    =========
Code              1100 0010
A                 1100 0001
XOR               0000 0011
X'01'             0000 0001
MIN               0000 0001
X'01'             0000 0001
XOR               0000 0000
X'F0'             1111 0000
OR                1111 0000

Binary 11110000 is hex F0, which is the character zero. All records that do not have a code of A generate a zero.

A1D converts the character result of the logical operations to a decimal one or zero. COUNTA adds the ones and zeros. Here are the results.

FULLCOUNT  ASSNCOUNT  COUNTA
=========  =========  ======
      10          6       4

To count a different value, change the 'A' in the innermost parentheses. For example, here's how to count records with code Z.

'%or(%xor(%min(%xor(Code ''Z'') X''01'') x''01'' ) x''F0'')'

Let me end with a few editorial comments.

First, I'm happy that Dave got his program to work.

Second, I did not suggest to him, but I'll suggest here, that SQL would offer a much better choice.

select count(*),                                          
       sum(case code when 'A' then 1 else 0 end) as ACount
   from data                                 

Unfortunately, I find that many shops don't have SQL. Which brings me to my third comment.

Third, I find that many shops are still writing the same style of code that was being written 20 years ago. Not long ago, I was talking to a developer who had been told, "You can read that Guru newsletter, but you can't do any of the stuff they talk about in it." No subprocedures. No SQL. I look at code like the mapped field expressions in the examples above and I groan. I like everything to be straightforward, as obvious and as intuitive as possible. But as long as some shops remain in the Dark Ages, I'll keep trying to publish techniques to help them get their jobs done.

Have a nice day.

--Ted



                     Post this story to del.icio.us
               Post this story to Digg
    Post this story to Slashdot


Sponsored By
WORKSRIGHT SOFTWARE

Do you need area code information?
Do you need ZIP Code information?
Do you need ZIP+4 information?
Do you need city name information?
Do you need county information?
Do you need a nearest dealer locator system?

We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

Just call us and we'll arrange for 30 days FREE use of either
ZIP/CITY or PER/ZIP4.

WorksRight Software, Inc.
Phone: 601-856-8337
Fax: 601-856-9432
E-mail: software@worksright.com
Web site: www.worksright.com


Senior Technical Editor: Ted Holt
Technical Editors: Howard Arner, Joe Hertvik, Shannon O'Donnell, Kevin Vandever
Contributing Technical Editors: Joel Cochran, Wayne O. Evans, Raymond Everhart,
Bruce Guetzkow, Brian Kelly, Marc Logemann, David Morris
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.

Sponsored Links

COMMON:  Join us at the Annual 2008 conference, March 30 - April 3, in Nashville, Tennessee
BCD:  The best integrated System i Modernization software from one vendor
Krengeltech:  Create XML Web Services from RPG - without Java or Websphere


IT Jungle Store Top Book Picks

The System i Pocket RPG & RPG IV Guide: List Price, $69.95
The iSeries Pocket Database Guide: List Price, $59.00
The iSeries Pocket Developers' Guide: List Price, $59.00
The iSeries Pocket SQL Guide: List Price, $59.00
The iSeries Pocket Query Guide: List Price, $49.00
The iSeries Pocket WebFacing Primer: List Price, $39.00
Migrating to WebSphere Express for iSeries: List Price, $49.00
iSeries Express Web Implementer's Guide: List Price, $59.00
Getting Started with WebSphere Development Studio for iSeries: List Price, $79.95
Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00
Getting Started with WebSphere Express for iSeries: List Price, $49.00
WebFacing Application Design and Development Guide: List Price, $55.00
Can the AS/400 Survive IBM?: List Price, $49.00
The All-Everything Machine: List Price, $29.95
Chip Wars: List Price, $29.95

 

The Four Hundred
The i5 515 and 525 Versus the Unix Competition

Vision Solutions Acquires HA Rival Lakeview Technology

Adoption of VoIP Tied to Relief from Phone Expenses

The Web Runtime Tax: The Tax Man Cometh, Again

The Linux Beacon
Linspire Hooks Up with Microsoft, Too

Intel Bangs the Itanium Drum, Draws Out Roadmap

Novell Ships Service Pack 1 for SUSE Linux 10

Torvalds Says Linux May Follow Solaris with GPL v3

Four Hundred Stuff
IBM Taps Nortel for Entry-Level System i VoIP Solution

North Carolina Schools Laud SafeData for Online DR Solution

NGS Hooks Into Query/400 to Protect BI Investments

S4i Expands File Support in Document Management Software

Big Iron
IBM Brings Freebie PHP to the Mainframe

Top Mainframe Stories From Around the Web

Chats, Webinars, Seminars, Shows, and Other Happenings

System i PTF Guide
June 16, 2007: Volume 9, Number 24

June 9, 2007: Volume 9, Number 23

June 2, 2007: Volume 9, Number 22

May 26, 2007: Volume 9, Number 21

May 19, 2007: Volume 9, Number 20

May 12, 2007: Volume 9, Number 19

The Windows Observer
Microsoft Patches 17 Flaws in Client Products

Microsoft Stretches 'Vision Thing' with Surface Computing

Microsoft Updates Server Virtualization Software

Sun Broadens Its Blade Server Lineup

The Unix Guardian
Apple Previews Mac OS X 10.5 'Leopard' Server

CIOs Get Ready to Hire in the Summer

Open Source Software Sales Pegged at $5.8 Billion by 2011

As I See It: The Ne'er-Do-Well's Guide to Enlightenment

Four Hundred Monitor
Four Hundred Monitor's
Full iSeries Events Calendar

THIS ISSUE SPONSORED BY:

Help/Systems
WorksRight Software
Guild Companies



TABLE OF CONTENTS
Parameter Passing and Performance

Conditional Counting with Open Query File

What Is SMIOSTCPGT and Why Is It Eating My System?

Four Hundred Guru

BACK ISSUES

From the IT Jungle Forums
Stuck in the Dark Ages

Referencing the key of current record

FNDSTRPDM Output Member Name to *OUTFILE

Brother HL 6050 printing '$' instead of '£' symbol

XML





 
Subscription Information:
You can unsubscribe, change your email address, or sign up for any of IT Jungle's free e-newsletters through our Web site at http://www.itjungle.com/sub/subscribe.html.

Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc., 50 Park Terrace East, Suite 8F, New York, NY 10034

Privacy Statement