• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Thinking in Sets

    March 31, 2004 Hey, Howard

    I have an interesting problem and was wondering if you could show me how to code it in SQL. I have a file that records changes to packages in our facility. The file has a package ID number, date of activity, time of activity, and activity code. I want to find the last date and time of activity for each package but can’t get the query to work, because using MAX on the date and time can return a time value for when an activity did not occur.

    –Michael

    This is a really interesting problem, Michael, because your schema does not use the timestamp data type, but rather two separate fields–a date and a time–to record the activity. However, thinking in sets and relating the sets together can solve this problem.

    First, I’ve created a small sample table to insert data for test queries:

    CREATE TABLE SQLBOOK.T1AA
    	(ID INTEGER NOT NULL,
    	 ACTDATE	DATE NOT NULL,
    	 ACTTIME 	TIME NOT NULL);
    	
    INSERT INTO SQLBOOK.T1AA VALUES (1,'01/01/2003','01:00');	
    INSERT INTO SQLBOOK.T1AA VALUES (1,'01/02/2003','02:00');	
    INSERT INTO SQLBOOK.T1AA VALUES (1,'01/03/2003','03:00');	
    INSERT INTO SQLBOOK.T1AA VALUES (2,'01/01/2003','02:00');	
    INSERT INTO SQLBOOK.T1AA VALUES (3,'01/02/2003','03:00');	
    INSERT INTO SQLBOOK.T1AA VALUES (3,'01/03/2003','02:00');	
    INSERT INTO SQLBOOK.T1AA VALUES (3,'01/04/2003','01:00');
    

    If you query the table you should get results like the following:

    ID

    ACTDATE

    ACTTIME

    1

    01/01/2003

    1:00:00 AM

    1

    01/02/2003

    2:00:00 AM

    1

    01/03/2003

    3:00:00 AM

    2

    01/01/2003

    2:00:00 AM

    3

    01/02/2003

    3:00:00 AM

    3

    01/03/2003

    2:00:00 AM

    3

    01/04/2003

    1:00:00 AM

    Now, one would assume that you could simply code a query using max and achieve the desired results, but doing that query leads to data that is not in the result set. Here is an example:

    SELECT ID, MAX(ACTDATE) AS D, MAX(ACTTIME) AS T
    FROM SQLBOOK.T1AA
    GROUP BY ID;
    

    That query would result in the following:

    ID

    D

    T

    1

    01/03/2003

    3:00:00 AM

    2

    01/01/2003

    2:00:00 AM

    3

    01/04/2003

    3:00:00 AM

    What’s wrong with the above result set? Notice that result for ID 3 says that the last activity occurred on 1/4/2003 at 3:00 AM; however, if you look at the source data, the activity on 1/4/2003 occurred at 1:00 AM. By using MAX, you are creating a result set of incorrect data. Now, consider the following query:

    SELECT ID, MAX(ACTDATE) AS D
    FROM SQLBOOK.T1AA
    GROUP BY ID;
    

    This query returns a set I will call X:

    ID

    D

    1

    01/03/2003

    2

    01/01/2003

    3

    01/04/2003

    The above query returns a result set that correctly identifies the date of each last activity. What you need to do is join that result set back to the table to retrieve the time of the last activity on the given date. Here is a query that returns the last time of an activity for a given ID on each date:

    SELECT ID, ACTDATE, MAX(ACTTIME) AS T
    FROM SQLBOOK.T1AA
    GROUP BY ID, ACTDATE;
    

    This query returns a set I will call Y:

    ID

    ACTDATE

    T

    1

    01/01/2003

    1:00:00 AM

    1

    01/02/2003

    2:00:00 AM

    1

    01/03/2003

    3:00:00 AM

    2

    01/01/2003

    2:00:00 AM

    3

    01/02/2003

    3:00:00 AM

    3

    01/03/2003

    2:00:00 AM

    3

    01/04/2003

    1:00:00 AM

    Why did I elect to use MAX in returning the time? Just in case there are several entries for the same day. Remember, I want the last time that something happened to a given ID on a date. If I have more than one record for a single ID on a given date, without using MAX and a group by the query would return two records. Now that I have two sets of data (X and Y in the above examples), I can simply join them together to find the date and time of the last activity:

    SELECT X.ID, D, T
    FROM (SELECT ID, MAX(ACTDATE) AS D
    		FROM SQLBOOK.T1AA
    		GROUP BY ID) AS X
    	INNER JOIN 
    		(SELECT ID, ACTDATE, MAX(ACTTIME) AS T
    		 FROM SQLBOOK.T1AA
    		GROUP BY ID, ACTDATE) AS Y
    	ON (X.ID=Y.ID AND X.D = Y.ACTDATE);
    

    Results in this set:

    ID

    D

    T

    1

    01/03/2003

    3:00:00 AM

    2

    01/01/2003

    2:00:00 AM

    3

    01/04/2003

    1:00:00 AM

    See, the above query uses an inner join to join the set X to the set Y, where the ID codes are equal and the dates are equal. In this manner, I get a set of information showing the last date and time of an activity against an ID code.

    Remember, a table is just a set of data. An SQL statement is a set of data. SQL allows you to join sets of data together. If you think in sets, relational gets a whole lots easier and opens up a lot of possibilities in your queries and reporting. Besides, it’s fun.

    Howard F. Arner, Jr., is a writer and consultant with Client Server Development and is the author of the book iSeries and AS/400 SQL at Work. Howard also designed SQLThing Enterprise Edition, a query program and stored procedure editor specifically for the AS/400’s unique capabilities. You can purchase a copy of Howard’s book or learn more about SQLThing or SQL on the iSeries at www.sqlthing.com. Send your SQL questions to Howard at harner@sqlthing.com.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Focal Point Solutions Group

    Comprehensive Data Protection from Focal Point SG

    Your organization needs to be thinking differently about your backup & disaster recovery strategy

    Concerns of the Industry

    • Inefficient manual backup processes
    • Effectively storing data offsite
    • Developing and testing a concrete disaster recovery plan
    • Efficient access to data in a disaster scenario for necessary users
    • Risk of cyber security attack
    • Declining IT staff and resources

    The true cause of the above concerns is an organization’s status quo – 80% of IBM i users currently backup to tape and 40% of companies have no DR plan at all. Don’t wait for a disaster to take action.

    The new way to ensure cost-effective safety

    • Automated cloud backup
    • Two (2) remote sites – redundant storage, power, internet pipe, firewalls, etc.
    • Data encryption at all times – in-flight and at-rest
    • Fully managed remote hardware DR, including remote VPN access for necessary users
    • Regularly simulated phishing tests and cyber security training

    Potential “landmines” in solutions to avoid

    • Single point of storage – no redundancy
    • Misleading data analysis, compression/de-dup ratios, sizing of necessary computer resources for backup and DR
    • Large-scale cloud storage with difficult recovery
    • Inability to meet RTO/RPO

    Don’t get caught like the many organizations we’ve seen with inefficient exposed backup data and no DR plan!

    What VAULT400 has to offer

    Backup

    • Native software agent schedules backups to the Focal Point SG cloud based on your retention scheme
    • Client data is backed up to two data centers in US or two data centers in Canada
    • 256-bit AES encryption in-flight and at rest – only the client has the encryption key
    • Detailed data analysis to ensure proper sizing

    Disaster Recovery as a Service (DRaaS)

    • Focal Point SG provides “hands-off” DR – fully managed recovery
    • 60 days of remote VPN access available to unlimited users in event of a disaster
    • Documented reports to ensure defined SLAs are met

    Managed Service Cyber Security Training

    • Fully managed phishing tests
    • Detailed reporting of results
    • Fully managed administration of custom online cyber security training

    VAULT400 Cloud Backup & DRaaS is an IBM Server Proven Solution.

    VAULT400.com/proposal for FREE analysis & proposal

    813.513.7402 | ContactUs@FocalPointSg.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Bankers Will Soon Savor the Java of RIO Paychecks Up Slightly in OS/400 Shops

    Leave a Reply Cancel reply

Volume 4, Number 10 -- March 31, 2004
THIS ISSUE
SPONSORED BY:

Guild Companies
Client Server Development
GST
SuSE Linux
COMMON

Table of Contents

  • Step by Step: RPG IV and Interactive Web Pages
  • Determine Elapsed Days, Weekdays, and Workdays
  • Thinking in Sets
  • Admin Alert: Moving ASCII Data Between IFS and Windows
  • OS/400 Alert: Virus Programming for the Novice

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • IBM i Has a Future ‘If Kept Up To Date,’ IDC Says
  • When You Need Us, We Are Ready To Do Grunt Work
  • Generative AI: Coming to an ERP Near You
  • Four Hundred Monitor, March 22
  • IBM i PTF Guide, Volume 25, Number 12
  • Unattended IBM i Operations Continue Upward Climb
  • VS Code Is The Full Stack IDE For IBM i
  • Domino Runs on IBM i 7.5, But HCL Still Working on Power10
  • Four Hundred Monitor, March 6
  • IBM i PTF Guide, Volume 25, Number 11

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2023 IT Jungle