OBIEE expression to filter by previous business date - sql

I am trying to come up with solution to generate automatic OBIEE 12 report generating automatically for previous business date (e.g. when generating report on Monday, would like to filter data from Friday). I came up with two solutions:
CURRENT_DATE-1
Which obviously works well only for reports generated on Tuesday - Saturday.
I came up also with a more sophisticated solution, which returns no results (do not know why):
CASE
WHEN DayOfWeek(TimestampAdd (SQL_TSI_DAY, -1 , CURRENT_DATE)) = 1
THEN TimestampAdd (SQL_TSI_DAY, -3 , CURRENT_DATE)
WHEN DayOfWeek(TimestampAdd (SQL_TSI_DAY, -1 , CURRENT_DATE)) = 7
THEN TimestampAdd (SQL_TSI_DAY, -2 , CURRENT_DATE)
ELSE TimestampAdd (SQL_TSI_DAY, -1 , CURRENT_DATE)
END
When using this expression for filtering date, OBIEE returns info that no data is matched. For the same date proper results are generated with CURRENT_DATE-1 (ofc besides reports generated on Mondays, Saturdays and Sundays)

This might work for you:
case trim(to_char(sysdate,'DAY'))
when 'MONDAY' then sysdate-3
when 'SUNDAY' then sysdate-2
else sysdate-1
end
Returns the date of previous business day before now.
Bobby

Related

Rolling back on query one day before SQL

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?
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.
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.

Two columns with dates (one any day of week, another one WEEK ENDING DATE (SATURDAY) BASED ON 1st column)

I have such a situation.
I need to have 2 columns 1) Is just pull data from a table (just as it is) r.[RCLDTE] (Day of week)
and 2 column) I need to basically look at the first column and make it Saturday of that week.
SELECT r.[RCLDTE] AS 'Day of Week'
,r.[RCLDTE] AS 'Week Ending Day (Saturday)'
Before what I was doing at similar projects I just used this code and added to WHERE statement.
WHERE CONVERT(DATE, CONVERT(CHAR(8), r.[RCLDTE] )) = cast(DATEADD(dd, DATEPART(DW,GETDATE())*-1, GETDATE()) as date)
This code was changing the dates column to Saturday.
However, here I have a different situation. I need 2 columns 1) as it is and 2) where dates will be Saturdays of the week from r.[RCLDTE] column , as a result from the way how I understand I cannot use WHERE statement because it will affect both columns.
Does someone know how I can leave 1st column as it is and 2nd a column of Saturday.
Please let me know.
Thanks.
To avoid issues when someone changes either DATEFIRST or LANGUAGE settings, you can use this. Also, given that you are storing dates in a numeric column for some reason (you really should provide feedback to whoever owns the system so they can fix it), we have to first try to convert those values to a date (they may not all be valid, which is one of the problems with using the wrong data type):
;WITH t AS
(
SELECT *, ProperDate = CASE WHEN ISDATE(CONVERT(char(8), RCLDTE)) = 1
THEN CONVERT(date, CONVERT(char(8), RCLDTE)) END
FROM dbo.tablename
)
SELECT [Language] = ##language, [Datefirst] = ##datefirst,
RCLDTE = CASE WHEN ProperDate IS NULL THEN RCLDTE END,
[Day of Week] = ProperDate,
[Saturday] = DATEADD
(
DAY,
6 - ((DATEPART(WEEKDAY, ProperDate) + ##DATEFIRST - 1) % 7),
ProperDate
)
FROM t;
Updated db<>fiddle that also demonstrates the handling of garbage data and a version of SQL Server so old that TRY_CONVERT() didn't exist yet (at least 12 years ago).
here is one way :
select
r.RCLDTE AS 'Day of Week'
, dateadd(day, 7 - datepart(weekday, r.RCLDTE) , r.RCLDTE)
from tablename r
db<>fiddle here

Getting Last Day of Month (2 Months Ago) in ODBC

I'm trying to get the last day of 2 months ago on an ODBC server but can't seem to get it quite right as the EOMONTH built-in function of SSMS is not functional in ODBC.
The part of the code that I currently have in my WHERE clause returns the 1st day of the last month. I'm trying to get the day before that, which would be as described, the last day of 2 months ago.
Here's the code that I'm currently using:
WHERE x_date = cast(dateadd(month, -1, dateadd(day, 1 - day(getdate()), getdate())) as date)
Currently, we are May 7th, 2021. That WHERE clause returns me April 1st, 2021. I would like it to return me March 31st, 2021.
I've tried other WHERE clauses, without any positive results.
Any help would be greatly appreciated.
Thank you.
you can use EOMONTH function in sql server :
SELECT EOMONTH(GETDATE(), -2)
if it is not supported then this should work:
SELECT DATEADD(dd,-(DAY(DATEADD(mm,-1,getdate()))),DATEADD(mm,-1,getdate()))
by open day if you mean weekdays:
select case DATENAME(weekday , <above date>)
when 'Saturday' then dateadd(day , 2 , <above date>)
when 'sunday' then dateadd(day , 1 , <above date>)
else <above date>

Business Week logic in Oracle SQL

I am using the following Oracle SQL query to work out if a week is more than 6 business weeks ago.
,CASE
WHEN to_char(next_day(CURRENT_TIMESTAMP,'sunday'),'iw')-6 <= to_char(next_day(m.COMPLETED_DT,'sunday'),'iw') THEN 'Yes'
ELSE 'No' END AS "Completed.Prior 6 Weeks"
The trouble is that this statement does not take into account the year, so now it is 2015, the business week is 1 and everything in the previous year has a greater business week.
I some how need to take into account the year as well, something like the below kind of works, but doesn't take into consideration the Business Week.
CURRENT_TIMESTAMP -42 >= m.COMPLETED_DT
Any help greatly appreciated
Rather than using TO_CHAR() to get the business week (which I think means the week starting on Monday), you should use TRUNC() - this way the year is preserved:
, CASE WHEN TRUNC(NEXT_DAY(SYSDATE, 'sunday'), 'iw') - 42 >=
TRUNC(NEXT_DAY(m.COMPLETED_DT, 'sunday'), 'iw') THEN 'Yes'
ELSE 'No' END AS "Completed.Prior 6 Weeks"
Note that I used 42 instead of 6 as Oracle date arithmetic uses days.
I'm not sure I see an advantage to using CURRENT_TIMESTAMP over SYSDATE. If you want to use the ANSI standard, you would want CURRENT_DATE ... I don't think you need the granularity of CURRENT_TIMESTAMP here, especially since you're truncating it. Also, you had <= when I think you mean >= (from what you have later in the question).

Business Days calculation

I have a query where I am calculating total days between two days including start and end date by the following SQL query. If the end date is not null, then end date is considered as current date.
This query does the job. But I do not want to count Sat and Sundays. Possible public UK Holidays.(I can do this one, if I can get the logic for Saturdays and Sundays)
SELECT DateDiff(day,DateADD(day,-1,StartDate),ISNULL(EndDate,getDate()))numberOfDays
FROM <mytable>
How do I count only weekdays between two dates?
Thank you
I would strongly recommend a calendar table for this, especially if you need to take specific holidays into account. Calculating Easter dynamically, for example, is going to be a royal pain.
http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
If you're going to use T-SQL alone, be careful about using functions that rely on regional/language settings for the output of things like DATENAME ...
Take a look at the DATEDIFF MSDN page.
At the bottom of the page, there is some user-generated content.
One user posted a function there which does exactly what you want, including holidays (headline: "UDF to return the number of business days, including a check to a bank holidays table").
try this
SELECT DateDiff(day,DateADD(day,-1,StartDate),ISNULL(EndDate,getDate())) -
( CASE WHEN DATENAME(dw, StartDate) = 'Sunday' OR
DATENAME(dw,ISNULL(EndDate,getDate())) = 'Sunday' THEN 1 ELSE 0 END)
- ( CASE WHEN DATENAME(dw, StartDate) = 'Saturday' OR
DATENAME(dw,ISNULL(EndDate,getDate())) = 'Saturday' THEN 1 ELSE 0 END)
numberOfDays
FROM <mytable>