Calculate difference in months between dates in SAS DS2 - sas-ds2

How can I calculate the difference in months between two dates in DS2?
In other words, is there and alternative to the classical INTCK?

Related

Date table lookup efficiency - MySQL

I need to calculate the number of "working minutes" between two datetime values, lets call them 'Created' and 'Finished'.
'Finished' is always subsequent to 'Created'. The two values can differ by anything from 1 second to several years. The median difference is 50,000 seconds or roughly 14 hours.
Working minutes are defined as those occurring between 0900 to 1700 hours, Monday to Friday; excluding weekends and official holidays in our country.
I decided a lookup table was the way to go, so I generated a table of all work minutes, explicitly excluding weekends, nights and holidays...
CREATE TABLE `work_minutes` (
`min` datetime NOT NULL,
PRIMARY KEY (`min`),
UNIQUE KEY `min_UNIQUE` (`min`)
)
I populated this programatically with all the "working minutes" between years 2017 to 2024, and at this point I started to get the feeling I was being very inefficient as the table began to balloon to several hundred thousand rows.
I can do a lookup easily enough, for instance:
SELECT COUNT(min) FROM `work_minutes` AS wm
WHERE wm.min > '2022-01-04 00:04:03'
AND wm.min <= '2022-02-03 14:13:09';
#Returns 10394 'working minutes' in 0.078 sec
This is good enough for a one-off lookup but to query a table of 70,000 value pairs takes over 90 minutes.
So, I am uncomfortable with the slowness of the query and the sense that the lookup table is unnecessarily bloated.
I am thinking I need to set up two tables, one just for dates and another just for minutes, but not sure how to implement. Date logic has never been my forte. The most important thing to me is that the lookup can query over 70,000 values reasonably quickly and efficiently.
Working in MySQL 5.7.30. Thanks in advance for your expertise.
Divide the timerange to 3 parts - starting and finishing incomplete day parts, and middle part which consists from a lot of complete days. Of course if both starting and finishing time stamps have the same date part then it will be one part only, if their dates are consecutive then you\ll have 2 parts to process.
There is no problem to calculate the number of working minutes in incomplete day part. Common overlapping formula with weekday checking will help.
Create static calendar/service table which starts from the date which is earlier than any possible date in your beginning timestamp with guarantee and includes all dates after any possible date in your finishing timestamp. Calculate cumulative working minutes for each date in the table. This table allows to calculate the amount of working time in any range of complete days with single substraction.
Plan A: Convert the DATETIME values to seconds (from some arbitrary time) via TO_SECONDS(), then manipulate them with simple arithmetic.
Plan B: Use the DATEDIFF() function.
Your COUNT(min) counts the number of rows where min IS NOT NULL. You may as well say COUNT(*). But did you really want to count the number of rows?

Count the number of columns in a column group

I need to report the average number of customer visits each engineer makes per month.
My SQL query creates a temporary table of months between the start date and end date and left joins this to the main data table, to ensure rows are returned even for months where no visits were made.
So an example of the data returned from SQL may be:
My report has two column groups, one for year and one for month, and I have a row group for the engineer.
For this report, the date is always returned as the first of the month, even though the actual visit could be on any date.
At the end of each year there is a cell which contains Count(Customer) and totals the number of visits the engineer made in that year. I would also like to have a cell which displays the average number of visits made each month in that year.
For a complete year I could simply divide by 12. However for a partial year I need to count the number of month columns for that year.
I tried CountDistinct(Month) but this only counts months where at least one visit was made, making the monthly average incorrect.
How can I get a count of the number of columns in a column group, including columns with no data?
Thanks.
The way I would do this would be to add a column into your temporary dates table that had the number of months selected in it.
You could do this by either counting the months in the temp table then appending the value to it or, if the dates table contains more than just months then work it out based on the parameters you pass in.
For example
SELECT *, DATEFIFF("m", #startDate, #endDate) as NoOfMonths
INTO #myTempDateTable
FROM myDateTable
WHERE etc...
Then in SSRS you can simply divide your total by this number.

Displaying number of years worked since joined date

List all keepers that earn more than $37,000 a year at the zoo. Show the keepers name, the total salary for a year (assume 38hrs week) and the number of years they have worked at the zoo.
Select surname
, given
, RatePerHour*38*52
From Keeper
Where ‘ratePerHour’ *38*52 > 37000
This is what i've got so far, not sure how I'm supposed to display number of years worked?
Theres a "joined" table that shows date joined at the company.
I thought about trying '2019-03-08' - 'Joined' but that displayed the incorrect answer.
My best guess would be to utilize mySql's CURDATE() function to fetch the current date rather than hard coding today's date.
Then you can use DATEDIFF(%FutureDate%, %PastDate%) function to calculate the number of days worked and finally convert those number of days in a yearly representation.

Getting the number of days excluding years between two dates

I want to get the number of days ignoring year between two dates in MySql.
I am using the following query, which works fine when the dates are more than a year apart.
select dayofyear(from_days((to_days('2015-11-20') - to_days('2014-11-15'))))
select dayofyear(from_days((to_days('2019-11-20') - to_days('2014-11-15'))))
correctly both return 5
However when the two dates are in the same year
select dayofyear(from_days((to_days('2014-11-20') - to_days('2014-11-15'))))
this returns 0. I think this is because MySql has a problem with dates in years less than 100 (or at least the dayofyear function has).
Is there any way around this?
Absent your willingness to specify what happens on leap years, one is forced to guess.
I think this works. http://sqlfiddle.com/#!2/043543/1/0
IF(timestampdiff(DAY, st, str_to_date(concat_ws('-',YEAR(st),MONTH(fi), DAY(fi)),'%Y-%m-%d')) >= 0,
timestampdiff(DAY, st, str_to_date(concat_ws('-',YEAR(st),MONTH(fi), DAY(fi)),'%Y-%m-%d')),
timestampdiff(DAY, st, str_to_date(concat_ws('-',YEAR(st)+1,MONTH(fi), DAY(fi)),'%Y-%m-%d'))) delta
It tacks the starting year onto the ending day and tries to compute the number of days. Then, if that comes up negative, it tacks the year after the starting year onto the starting day and computes the number of days.
You are complicating this issue for nothing;
There is a DATEDIFF function in MySQL that allow you to do that.
SELECT DATEDIFF('2006-04-03','2006-04-01');
That would return 2 (days).
To get the result regardless of the year, then apply % 365.
Edit : If you want to get the exact number of days considering leap years, you could substract to the number of days, the number of days for both year at 1st january (or any other date) :
SELECT DATEDIFF('2006-04-03','2006-04-01') - DATEDIFF(concat(year(yourDate), '01-01'), concat(year(yourDate2), '01-01'));
This will substract the total number of days between 1st january of each year to the total number of days.

How to get month using date in MySQL [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
how do I get month from date in mysql
I want to get month using date example 2011-04-02 so I want month april. How to get this in MySQL?
SELECT MONTHNAME(date) AS monthName for January, February...
SELECT MONTH(date) AS monthName for 1, 2...
SELECT MONTHNAME(`date`) AS month_name FROM table_name;
You can use MONTHNAME() to get the month name. If you want month number, consider to use MONTH()
You can have a much more elegant solution to this if you use a second table as a date dimension table, and join your date field to it, in order to extract more useful information. This table can contain dates, month names, financial quarters, years, days of week, weekends, etc.
It is a really tiny table, only 365(ish) rows per year of data you have... And you can easily write some code to populate this table with as much data as you require. I did mine in Excel, exported as a CSV file and then imported the data into a blank table.
It also gives lots of benefits, for example, imagine a monthly data table with the following fields (and any others you can think of!) fully populated for all the months in a given range;
Date (E.g. 2009-04-01)
Day (E.g. 1)
Day of Week (E.g. Wednesday)
Month (E.g. 4)
Year (E.g. 2009)
Financial Year (E.g. 2009/10)
Financial Quarter (E.g. 2009Q1)
Calendar Quarter (E.g. 2009Q2)
Then combining this with your own table as follows;
SELECT `DT`.`monthName`
FROM `your_table`
INNER JOIN `dateTable` as DT
ON `your_table`.`your_date_field` = `dateTable`.`theDate`
There are many other nice outputs that you can get from this data.
Hope that helps!