Home > Net >  Rolling back on query one day before SQL
Rolling back on query one day before SQL

Time:06-13

I am trying to make a query in which for every weekday, it picks always the last business day, except for Mondays. On Mondays, it should always pick the last Friday.

To achieve this, it could be either done by selecting or creating an additional column that allows to identify these cases.

Examples:

  • If first_date = Tuesday then pick Monday
  • If first_date = Thursday then pick Wednesday
  • If first_date = Monday then pick Friday

Here my query:

SELECT name, 
       first_date, 
       last_day, 
       product, 
       TO_DATE(first_date) - TO_DATE(last_day) AS d, 
       CASE WHEN TO_CHAR(first_date, 'D') = '7' THEN -2
            WHEN TO_CHAR(first_date, 'D') = '6' THEN -1
            ELSE 0
       END
FROM t1.mydata
WHERE d > 50

Any ideas on how to do this best?

CodePudding user response:

You can use conditional with TO_CHAR conversion along with Dy (or Day) argument rather than using those integer representations, those might fail for some regions, for weekdays such that

SELECT CASE WHEN TO_CHAR(your_datecol,'Dy','NLS_DATE_LANGUAGE=English') ='Mon' THEN 
                  'Fri'
            WHEN TO_CHAR(your_datecol,'Dy','NLS_DATE_LANGUAGE=English') = 'Sun' THEN    
                  Null
            ELSE 
                 TO_CHAR(your_datecol-1,'Dy','NLS_DATE_LANGUAGE=English')
             END AS last_business_day          
  FROM your_table

ignoring the local offical vacancies.

CodePudding user response:

You can use TRUNC(first_date) - TRUNC(fisrt_date, 'IW') to compare the date (truncated to midnight) to the start of the ISO week (which is always midnight on Monday). This will work regardless of the NLS_DATE_LANGUAGE or NLS_TERRITORY settings.

SELECT name, 
       first_date, 
       last_day, 
       product, 
       last_day - first_date AS d,
       first_date
       - CASE TRUNC(first_date) - TRUNC(fisrt_date, 'IW')
         WHEN 0 THEN -3 -- Monday
         WHEN 6 THEN -2 -- Sunday
                ELSE -1 -- Other days
         END AS prev_business_day
FROM   t1.mydata
WHERE  last_day - first_date > 50

Note: If you use TO_CHAR(first_date, 'D') then if the day is Monday then it will return: 1 in most of Europe; 2 in America; 3 in some Middle-Eastern countries; and 4 in Bangladesh as they all consider the first day of the week to be a different day db<>fiddle. This is based on the NLS_TERRITORY setting and is not something that can be overridden in the query.

Note: If you use TO_CHAR(first_date, 'Dy') then it will use the NLS_DATE_LANGUAGE session parameter to set the date language so your query would only work in one language. You would need to specify a third argument (i.e. TO_CHAR(first_date, 'Dy', 'NLS_DATE_LANGUAGE=English')) for it to work consistently in an International setting.

  • Related