Derive date column based on current date and fixed start date - sql

I have the following two columns:
date (datetime),
month_after_release (int)
These columns are filled monthly as part of an incremental update.
Let's say there was a release on Jan 1, 2015. This means we are currently in the 9th month after release [formula: round off((current date - release date)/30,0)+1 = 9] . So if I am now importing data with a current date (Sep 21, 2015), the two columns should be filled like this:
date = 2015-09-21 00:00:00.000
month_after_release = 9
In October, data which gets imported should then get the following information:
date = 2015-10-21 00:00:00.000
month_after_release = 10
How can I achieve this? One possibility which came to my mind would be to have a separate mapping table, which maps every single date to "month_after_release", but I was wondering if there is a better possibility?
The information when a release was is stored in a separate table, which looks like this:
ReleaseID,
Release_start_date

select releaseDate, DateDiff(MM, releaseDate, getdate()) MonthsSinceRelease
from table t
That's how you calculate it.

Related

Get past 6 months data from a table based on the recent date present in the column

I have a database table which is named as table and there is a column Col which is present in table with datatype varchar. Column Col contains dates in the format MMM-YY.
For example Col has values as :
Col
DEC-21
NOV-21
SEP-20
OCT-19
DEC-21
As, we can see data can be duplicated like DEC-21. I want to extract last 6 months data based on the recent month present in Col. For example, If the DEC-21 is the most recent date(consider, day is not present) and so, I want data from DEC-21 to JUN-21 i.e. 12-21 to 06-21 if we map DEC to 12 and JUN to 06. This Table has many columns and one of the columns is Col which I mentioned above and I have to extract data based on the column Col by using SQL query.
I have written a query as:
SELECT *
FROM table
WHERE CAST(RIGHT(Col,4) AS INT) Between 2020 and 2021
But here I get data between 2020 and 2021. So, By doing some modification in the above query or Is there any other way to get the past 6 months data from the recent date which is in MMM-YYYY format from Col column.
I was writing code in R and I was using dbGetQuery() where I have to pass the SQL query. I have already done this thing after storing it in a dataframe but is there any way to do it directly by sql query ?
Any help would be appreciated.
with data as (
select *,
convert(date, '01-' + dt, 105) as converted_dt,
max(convert(date, '01-' + dt, 105)) over () as last_converted_dt
from T
)
select * from data
where converted_dt >= dateadd(month, -6, last_converted_dt);
The 105 comes from the list of date formats which can be found in the documentation for cast/convert. SQL Server can convert strings like Apr 2021 so a cast like below might also work (if you actually have four-digit years) but it's best to be explicit about the format as I did above.
cast(replace(dt, '-', ' ' as date)
Something like this should work.
SELECT * FROM table where CONVERT(DATE,'01-'+Col) BETWEEN '01-Jun-2021' and '31-Dec-2021'

How to get all months between two dates in sql with data

Please suggest a method where in we could retrieve name of all months in between two dates.
The months may or may not contain data, but as the need is to display monthly trend, we are required to fetch all months in between two date ranges with or without data.
The Output will be like:
Jan | Feb | Mar
----------------------
Data | Data| Data
If you use SQL Server, you can use the MONTH() or DATEPART() function to extract the month from a date. For example, the following statement returns the current month in SQL Server: SELECT MONTH(CURRENT_TIMESTAMP); SELECT DATEPART(month, CURRENT_TIMESTAMP);
You could then do a GROUP BY to determine how many events occur per month
In general "dynamic columns" are much harder to achieve than "dynamic rows" so output that looks like the first of the tables below will be easier to achieve than output that looks like the second.
Easier
Month | Data
-------------
Jan | Data
Feb | Data
Mar | Data
Harder
Jan | Feb | Mar
----------------------
Data | Data | Data
In general, the best approach is to have your SQL queries return data in the first type of structure and then if required transform this to the second type in your "presentation layer", which might be in Excel, PowerBI, SSRS, or on a website, for example.
If you have months where there might be no data to be returned, you need some means of generating the months and then outer joining this to the data. Obviously in general, at least behind the scenes you'll want to be including years in your data in addition months as otherwise all the data from Jan 2020 will be grouped together with that from Jan 2021, which is probably not what you want.
Here is a SQL-Server-friendly snippet which will output all the months (and years) between two dates. At the time of writing, you haven't specified a DBMS, so if you aren't on SQL Server, this may not work for you.
DECLARE #datefrom DATE = '2020-06-01'
DECLARE #dateto DATE = '2021-03-01';
WITH cte AS
(
SELECT #datefrom as MyDate
UNION ALL
SELECT DATEADD(month,1,MyDate)
FROM cte
WHERE DATEADD(month,1,MyDate)<=#dateto
)
SELECT
YEAR(cte.MyDate) CalendarYear,
MONTH(cte.MyDate) CalendarMonth,
DATENAME(month, cte.MyDate) as MonthNameFull,
CONVERT(char(3),cte.MyDate,0) as MonthName3Char
FROM
cte
ORDER BY
Year(cte.MyDate),
Month(cte.MyDate)
The final SELECT query could be OUTER JOINed to your actual data to give you your desired results. Pivoting should then be done in the presentation layer.
An alternative to the cte would be to use a "numbers table" and use that to add a number of months to the start date and limit the output to where the result of adding that number of months is between the two provided dates.

Recurring Date Calculator SQL

I'm looking to create a recurring date calculator that will correspond to EVENTS on a specific calendar date. Each event has its own rule.
For example, for EVENT A rule is "Occurs Tuesday monthly with the start date Tuesday 9-17-2019. I'm using a time dimension table with every date populated until 2025. Using these dates I was using in the WHERE clause
WHERE dayname = 'tuesday' and ( DATEDIFF(DAY, '2019-09-17', Calendar_Date) % 28 ) = 0 to get monthly tuesdays.
But I'm running into issues when there are two 5 Tuesdays in a month. 3-3-2020 and 3-31-2020. Need date populated to be 4-7-2020 instead of 3-31-2020.
Can anyone help with a solution?
With your query, you're pretty close. All you need to do is to then sub-select
SELECT MIN(CalendarDate) AS CalendarDate
FROM (your query goes here) AS d
GROUP BY YEAR(CalendarDate), MONTH(CalendarDate);

Cumulative count in SQL

I am working on SQL and came across one scenario that needs to build in SQL.
Below is scenario:
PatientID AdmitDate DischargeDate
12 7/24/2017 09:45 7/24/2017 11:01
13 7/21/2016 08:37 7/22/2017 00:15
I want result set as below:
For patientID 13, count is calculated in first 2 rows and
For patientid 12, count is calculated in last row.
Well, that looks like whatever you do will be slow. I think I'd use a tally table. The table, instead of just containing the usual n years worth of dates / days / day of week etc. would also contain one record for each hour in the day. The Primary Key would represent one of those segments.
Then you could pass the admission date and discharge date for a patient to a function that would return a list, or range, of the hours that the patient is in for. So, Patient 13 might get a return value of (for example) 1500,1517 (i.e the patient was in for 17 hours and you will know the date and time because 1500 will be the Primary Key of a record that gives you the date and hour of the day he was admitted). Patient 12 would (to continue the example) return a value of 1544,1546
You could then build the dataset from Date A to Date B by returning all the data between those dates from the tally table and then check whether each hour is a yes or no for a particular patient.
The display of the data - your desired result set - I would do in somewhere else. I'd probably return two datasets. One would be used to build your table structure. The other would be used to decide whether to put a '1' in the box or not. You could do your summing on the fly.
I imagine this would get interesting with patients on the same dates ... you'd have to show each patient separately?

SSRS SQL I need to display data for dates used in the parameter and the previous month

I have an SSRS report with parameters for Created On Start and Created On End. Users run this manually and choose the date range to display records for. I need to display in two different columnns the records for the month the user entered in the parameters and the previous month for the dates used in the parameters.
For example the user uses the the following dates in the parameters:
Start Date: 03/01/2016 EndDate: 03/31/2016
The Report should display in one column the records for march 2016 and next to it the records for february 2016
You could write one query which queries both months.
Add a field that will act as the column label eg format the date as the first of the month.
Then create a pivot table to show the two months as the columns with the usual rows .
EDIT - new details
So:
dateStart = '2016-03-01'
dateEnd = '2016-03-31'
These could be less than the whole month, but should be in the same month. prevStart = DATEADD(month, DATEDIFF(month, '2000-01-01', dateStart)-1, '2000-01-01')
the first day of the previous month.
Use similar for the prevEnd to calculate the last day of previous month.
OK. Now build your select:
SELECT xxxx, yyyy, zzzz
, DATEADD(month, DATEDIFF(month, '2000-01-01', createdOnDate), '2000-01-01') as MonthCol
FROM tables
WHERE (createdOnDate>= prevStart and createdOnDate<=prevEnd)
OR (createdOnDate>= dateStart and createdOnDate<=dateEnd)
Build a pivot table style grid with monthCol as the heading of the columns and your usual data as the rows. That way you can get your "previous Month" columns as well as the date range that you selected