ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

SQL Date Arithmetic

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • SQL Date Arithmetic

    I have a file, I'll call MYFILE that has a field that represents a date. The field is named DATRES and is (8,0) S in YYYYMMDD format. I need to run this SQL command weekly that will delete records where DATRES converted to a date is more than a year old.

  • #2
    I plan to put this in an SQL program. Sorry, I don't have the capability to update my posts or I would changed the previous one

    Comment


    • #3
      If it's simply 1 year, you can subtract 10000 from YYYYMMDD to get 1 year ago. so 20200206 becomes 20190206. For more complicated date calculation, maybe you can find help here ?

      More about using SQL with date fields: using the functions DAY, DAYOFWEEK, WEEK, MONTH, YEAR, and the supported formats of dates

      Comment


      • #4
        Watch out subtracting 10000 from 20200229 (20190229 is an invalid date).

        Comment


        • #5
          Originally posted by MFisher View Post
          If it's simply 1 year, you can subtract 10000 from YYYYMMDD to get 1 year ago. so 20200206 becomes 20190206. For more complicated date calculation, maybe you can find help here ?

          More about using SQL with date fields: using the functions DAY, DAYOFWEEK, WEEK, MONTH, YEAR, and the supported formats of dates

          It could very well be something else beside 1 year, if the powers that be decide on differing criteria. I need to be able to do this whether it's 6 months, 30 days etc. I just picked 1 year arbitrarily

          Comment


          • #6
            Hi.

            An SQL approach could be:

            DELETE FROM MYFILE
            WHERE TO_DATE(CHAR(DATRES ), 'YYYYMMDD') < CURRENT_DATE - 1 YEAR;

            (Try with SELECT first)

            You can substitute "1 year" with "1 week", "1 day", "26 months"... whatever!

            Be sure in DATRES you always have a correct date, if not, you'll nedd to add extra sentences to avoid problems.



            Comment


            • #7
              Originally posted by inigo.redin View Post
              Hi.

              An SQL approach could be:

              DELETE FROM MYFILE
              WHERE TO_DATE(CHAR(DATRES ), 'YYYYMMDD') < CURRENT_DATE - 1 YEAR;

              (Try with SELECT first)

              You can substitute "1 year" with "1 week", "1 day", "26 months"... whatever!

              Be sure in DATRES you always have a correct date, if not, you'll nedd to add extra sentences to avoid problems.

              You are transforming the table column (DATRES) into a different format, to match the format of the comparison value ("current_date - 1 year"). In this case converting the numeric column to date type, to match against a date comparison value. This is inefficient because then the SQL engine cannot use any indexes that might exist on DATRES (unless someone explicitly created an index on "to_date(DATRES,'YYYYMMDD')" ).

              It's better to transform your comparison value to match the column format. I.e. transform the date "current_date - 1 year" to numeric yyyymmdd. This also avoids the issue of invalid dates in the table column.

              Code:
              select * from MYTABLE
               where DATRES < dec(current_date - 1 year,8,0)
              Converting a date to numeric using dec(<date>,8,0) puts it into yyyymmdd format

              Comment


              • #8
                Yes, you're right.
                That's what happens when you type fast and you don't think ;-)

                Better transform just once instead every record.

                Comment


                • #9
                  If you only need the numeric date without and a valid date is not important, so you simply can subtract 10000.
                  Converting a real date into a numeric date can now easily be done with the DEC scalar function.
                  But if you need to subtract 1 year from a numeric date and the resutl must be again a valid (numeric) date, the easiest way with SQL is:

                  Code:
                  Dec(Date(Digits(YourDate) concat '000000') - 1 Year, 8, 0)
                  Birgitta
                  Last edited by B.Hauser; February 7, 2020, 03:41 AM.

                  Comment


                  • #10
                    Birgitta, when I run that sentence, I get a null value:

                    Code:
                    values Dec(Date(Digits(20200207) concat '000000') - 1 Year, 8, 0);

                    Can I convert from numeric to date simply using the function DATE?

                    Comment


                    • #11
                      Code:
                      values Dec(Date(Digits(20200207) concat '000000') - 1 Year, 8, 0);
                      If you specify a number without decimal positions it is interpreted as integer ... and integer has 10 digits, so in your example the expression is 0020200207000000 which is NOT a valid character representation of a date or timestamp.
                      Your example should work if you change it as follows:
                      Code:
                      Values(Dec(Date(Right(Digits(20200207) concat '000000', 14)) - 1 Year, 8, 0));
                      You can convert a numeric date with the DEC scalar function if the numeric value represents the (calculated) number of days since 0001-01-01.
                      Code:
                      Values(Date(737462))
                      will return February, 7 2020.

                      Birgitta
                      Last edited by B.Hauser; February 7, 2020, 06:19 AM.

                      Comment


                      • #12
                        These are great tips, this is exactly what I need. Thanks to everyone.

                        Comment

                        Working...
                        X