So this code is from a previous person in my role (not myself) and I am trying to understand if it is completely useless or not. Still fairly new to SAS but my understanding of the Today() function is that it gives the number of days since 1/1/1960. This first statement and series of if/elses all depends on if today() returns a number less than 8, which certainly should never happen. Am i missing something or does this piece of code do nothing? (I certainty have changed code and forgotten to delete it before so they might not be insane but I'm just confused here).
data Dates;
rundate=mdy(1,1,year(today()));
if day(today()) >= 8 then do;
enddate=today()-3;
end;
else do;
if month(today()) ~= 1 then do;
if (month(today())-1) in (1,3,5,7,8,10,12) then do;
enddate=mdy(month(today())-1,31,year(today()));
end;
else if (month(today())-1) in (4,6,9,11) then do;
enddate=mdy(month(today())-1,30,year(today()));
end;
else do;
if year(today()) not in (2020,2024,2028,2032) then enddate=mdy(2,28,year(today()));
else enddate=mdy(2,29,year(today()));
end;
end;
else do;
enddate=mdy(12,31,year(today())-1);
end;
end;
You're missing a function!
if day(today()) >= 8 then do;
day() returns the day of the month - a number from 1 to 31.
So, this only does that first part if you're not in the first week of the month - a common thing in finance for example. If it's not the first week in the month, then the enddate for the period is 3 days ago. If it IS the first week in the month, then do the more complicated logic.
Related
How to find out Number of Workdays(Monday to Friday) between two dates in SAP HANA ? We do not have to consider holidays.
We cant use WORKDAYS_BETWEEN() as we do not have TFACS table.
Here is how you can so ist in sql:
Calculate the number of whole weeks, multiply by 5
Add the remaining days: subtract weekday start date from weekday end date, correct for weekends (least...), Correct for carry-over (+5)
The second part can be simplified a little so that you don't have to write the subtraction twice.
Here an example with start date '2015-12-04' and end date '2015-12-19):
SELECT ROUND( DAYS_BETWEEN (TO_DATE ('2015-12-04', 'YYYY-MM-DD'), TO_DATE('2015-12-19', 'YYYY-MM-DD')) / 7, 0, ROUND_DOWN) * 5
+ ( case
when WEEKDAY (TO_DATE('2015-12-19', 'YYYY-MM-DD') ) - WEEKDAY (TO_DATE('2015-12-04', 'YYYY-MM-DD')) >= 0
then least( WEEKDAY (TO_DATE('2015-12-19', 'YYYY-MM-DD')), 5) - least( WEEKDAY (TO_DATE('2015-12-04', 'YYYY-MM-DD')), 5)
else
least( WEEKDAY (TO_DATE('2015-12-19', 'YYYY-MM-DD')), 5) - least( WEEKDAY (TO_DATE('2015-12-04', 'YYYY-MM-DD')), 5) + 5
end )
"Workdays" FROM DUMMY;
--> 11
I preferred to create a user defined function here to use in HANA SQLScript codes as follows
Create Function CalculateWorkDays (startdate date, enddate date)
returns cnt integer
LANGUAGE SQLSCRIPT AS
begin
declare i int;
cnt := 0;
i := 0;
while :i <= days_between(:startdate, :enddate)
do
if WEEKDAY( ADD_DAYS(:startdate,:i) ) < 5
then
cnt := :cnt + 1;
end if;
i := :i + 1;
end while;
end;
Please note that the above code block seems to contain an unnecessary loop.
On the other hand, if you have additional tables like department holidays, or personal holidays, etc. It might be useful to check these tables in the WHILE loop. Please refer to following SQL tutorial Calculate the Count of Working Days Between Two Dates where I created a similar SQL function checking custom work calendars or holiday calendars.
Here is how you call the function as sample
select CalculateWorkDays('20170101', '20170131') as i from dummy;
I hope it helps,
I need to calculate a date in DB2 for UNIX.
I have a date field:
CONTRACT_DT (Examples:
2/7/2006,
8/25/2006,
11/16/2007,
2/25/2008,
12/29/2005)
And a type field
PRIME (Examples: C, I, E, Z, V, K)
I need to calculate the next date the loan will be reviewed (REVIEW_DT).
If Prime = Z then every year from CONTRACT_DT
If Prime = V then every three years from CONTRACT_DT
If Prime = K then every five years from CONTRACT_DT
If Prime = NULL or any other letter, then NULL
An example is loan 01 has a CONTRACT_DT of 3/1/2004, and has a PRIME of V.
So I need to count by/add three years to 3/1/2004, until I get a date greater than MTHLY_CLOSE_DT. (Options would be 2007, 2010, 2013, 2016, 2019,2022).
So correct answer is 3/1/2016.
I realize the structure is a CASE statement, but I have no idea how to pick a date based on year multiples and find the one greater than MNTHLY_CLOSE_DT.
Here's what I have so far:
CREATE PROCEDURE "FINANCE"."AL_LOOP_TEST"(OUT r_rvdt DATE)
BEGIN ATOMIC
DECLARE v_tmgi DATE;
DECLARE v_ctdt DATE;
DECLARE v_rvdt DATE;
SET v_tmgi = '2014-09-01'; --Close month
SET v_ctdt = '2012-06-02'; -- CONTRACT_DT
SET v_rvdt = v_ctdt; -- Starting Value for v_rvdt
WHILE (v_rvdt < v_tmgi) -- While Review Dt is less than Close Month
DO
SET v_rvdt = (v_rvdt + 5 YEAR); -- Add 5 years to date
END WHILE;
SET r_rvdt = v_rvdt;
END
Thanks!
Jimmy, Thanks for your help. This is what I created:
CREATE PROCEDURE "X"."AL_LOOP_TEST" ( OUT "R_RVDT" DATE )
LANGUAGE SQL
NOT DETERMINISTIC
EXTERNAL ACTION
MODIFIES SQL DATA
OLD SAVEPOINT LEVEL
BEGIN ATOMIC
DECLARE v_tmgi DATE;
DECLARE v_ctdt DATE;
DECLARE v_rvdt DATE;
SET v_tmgi = '2014-09-01'; --Close month
SET v_ctdt = '2002-06-02'; -- CONTRACT_DT
SET v_rvdt = v_ctdt; -- Starting Value for v_rvdt
WHILE (v_rvdt < v_tmgi) -- While Review Dt is less than Close Month
DO
SET v_rvdt = (v_rvdt + 5 YEAR); -- Add 5 years to date
END WHILE;
SET r_rvdt = v_rvdt;
END;
We have a report that was running perfectly using the iReport designer, and from the JasperReports Serer.
I made some minor modifications to the underlying MySQL stored procedure, and adjusted the report structure accordingly, and now I can run the report from the Designer interface, but not at all from the server.
I'm receiving an error as follows:
Error Message
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
Which I understand to be a problem with one of the dates we use in the report, but none of the date information changed that I am aware of.
I'll start by attaching the report, and the top section of the stored procedure:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_fasb`(start_date varchar(10), end_date varchar(10), loc varchar(45))
BEGIN
declare friday_end_date varchar(10);
declare in_str varchar(255);
if dayofweek(end_date) = 7 then
SET friday_end_date = date_add(end_date, interval 6 day);
else
SET friday_end_date = date_add(end_date, interval (6-dayofweek(end_date)) day);
end if;
if dayofweek(end_date) = 7 then
SET end_date = date_add(end_date, interval -1 day);
end if;
if dayofweek(end_date) = 1 then
SET end_date = date_add(end_date, interval -2 day);
end if;
Appreciate any suggestions.
From what I can see, all the date datatype is varchar(10).
Since you are using date_add functions, you cannot have your 'start_date' as a string.
When you try this on MYSQL
SELECT date_add(curdate(), interval 6 day);
Result:2013-05-06
But when you try
SELECT date_add('2013-04-30', interval 6 day);
You do not get any result or you get 'BLOB' which means it is expecting a variable of Date datatype inside the funcation.
Also in your report, may be you have your input parameter defined as java.util.Date.
You may want to change that and see if this is a problem with input parameter.
This could also be a problem.
Hope this helps.!
I'm not sure how to check for date ranges using a postgres function. What I want to do is check if a date falls within a certain range (with leeway of a week before the starting date)
So basically, I want to check if a date is between 7 days before to current date, and if so I'll return the id of that row.
create or replace function eight(_day date) returns text as $$
declare
r record;
check alias for $1;
startDate date;
begin
for r in
select * from terms
order by starting;
loop
startDate := r.starting;
if check between (..need help to create 7 days before startDate) and startDate return r.id;
end;
$$ language plpgsql;
I also have to check if the previous record's ending date collides with the startDate - 7days. How would I check the previous record?
Sounds like you want to use an interval:
startDate - interval '...'
I won't say any more than this since you're doing homework.
Dates work with integer math.
startdate - 8 is equivalent to (startdate::timestamp - '8 days'::interval)::date
I have a simple question regarding T-SQL. I have a stored procedure which calls a Function which returns a date. I want to use an IF condition to compare todays date with the Functions returned date. IF true to return data.
Any ideas on the best way to handle this. I am learning t-sql at the moment and I am more familar with logical conditions from using C#.
ALTER FUNCTION [dbo].[monday_new_period](#p_date as datetime) -- Parameter to find current date
RETURNS datetime
BEGIN
-- 1 find the year and period given the current date
-- create parameters to store period and year of given date
declare #p_date_period int, #p_date_period_year int
-- assign the values to the period and year parameters
select
#p_date_period=period,
#p_date_period_year = [year]
from client_week_uk where #p_date between start_dt and end_dt
-- 2 determine the first monday given the period and year, by adding days to the first day of the period
-- this only works on the assumption a period lasts a least one week
-- create parameter to store the first day of the period
declare #p_start_date_for_period_x datetime
select #p_start_date_for_period_x = min(start_dt)
from client_week_uk where period = #p_date_period and [year] = #p_date_period_year
-- create parameter to store result
declare #p_result datetime
-- add x days to the first day to get a monday
select #p_result = dateadd(d,
case datename(dw, #p_start_date_for_period_x)
when 'Monday' then 0
when 'Tuesday' then 6
when 'Wednesday' then 5
when 'Thursday' then 4
when 'Friday' then 3
when 'Saturday' then 2
when 'Sunday' then 1 end,
#p_start_date_for_period_x)
Return #p_result
END
ALTER PROCEDURE [dbo].[usp_data_to_retrieve]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF monday_new_period(dbo.trimdate(getutcdate()) = getutcdate()
BEGIN
-- SQL GOES HERE --
END
Thanks!!
I assume you are working on Sql2008. See documentation of IF and CASE keywords for more details.
CREATE FUNCTION dbo.GetSomeDate()
RETURNS datetime
AS
BEGIN
RETURN '2012-03-05 13:12:14'
END
GO
IF CAST(GETDATE() AS DATE) = CAST(dbo.GetSomeDate() AS DATE)
BEGIN
PRINT 'The same date'
END
ELSE
BEGIN
PRINT 'Different dates'
END
-- in the select query
SELECT CASE WHEN CAST(GETDATE() AS DATE) = CAST(dbo.GetSomeDate() AS DATE) THEN 1 ELSE 0 END AS IsTheSame
This is the basic syntax for a T-SQL IF and a date compare.
If you are comparing just the date portion for equality you will need to use:
select dateadd(dd,0, datediff(dd,0, getDate()))
This snippet will effectively set the time portion to 00:00:00 so you can compare just dates. So in use it will look something like this.
IF dateadd(dd,0, datediff(dd,0, fn_yourFunction())) = dateadd(dd,0, datediff(dd,0, GETDATE()))
BEGIN
RETURN SELECT * FROM SOMEDATA
END
Hope that helps!