Splitting business date into Day Month and year into separate columns - sql-server

My business intelligence tool is creating a lot of issues with calculating a variance YOY, instead, I am contemplating creating a view in my Database which will allow me to subtract two columns giving me the variance.
I am trying to wrap my head around the best way to go about this, been testing datepart, convert, cast on the date but I am sure I am going the wrong way about this.
select top 1
Business_date,
CONCAT(DATEPART(MM, Business_Date),'-', DATEPART(DD, Business_Date)) as
DayMonth,
case
when DATEPART(YYYY, Business_Date) = '2019' then 2019
end
from Occupancy_Forecast;
I know the code above does not give me anything where i need to be as I am trying to see the best way to do this, what I am looking for is something like the attached screenshot:
I have also included a screenshot of the current table I am reading from so you understand the current format

Using #Larnu statement regarding the pivot I have been able to create a view stored containing the data required using the below to give me the desired output:
select Resort as Resort, Business_Date as Date, [2016], [2017], [2018], [2019],
[2020]
from
(select Resort, business_date, DATEPART(YYYY, Business_Date) as Year, ADR
from Occupancy_Forecast
where Business_Date > '2015-12-31') as SourceTable
PIVOT
(
AVG(ADR)
FOR YEAR IN ([2016], [2017], [2018], [2019], [2020] )
) as PivotTable

Related

SQL query last instance before current range

I have a query that pulls all studies from the previous week based on the av_summary column. I need to add a column that will pull the study prior to the most recent study no matter how long ago the previous study was performed. I only need the date of the last study. f.creation_datetime is the column both current study and previous study would come from.
select distinct
f.patient_name
,t.patient_mrn
,p.accession_number
,p.performed_start_time
,p.procedure_id
,SUBSTRING(CAST(s.av_summary as NVARCHAR(MAX)), CHARINDEX('This suggests
the stenosis', CAST(s.av_summary as NVARCHAR(MAX))) ,
LEN(CAST(s.av_summary as NVARCHAR(MAX)))) as AV_Summary
,(select TOP 1 (p1.performed_start_time)
from dbo.T_TCS_PROCEDURE as p1
where
p1.patient_id = p.patient_id
and
p1.performed_start_time < p.performed_start_time
and p1.procedure_type_id = p.procedure_type_id
order by p1.performed_start_time DESC
) as Last_Echo
from dbo.folders as f
join dbo.T_TCS_PROCEDURE as p
on p.procedure_id = f.procedure_id
join dbo.T_ECHO_SUMMARY as s
on s.procedure_id = f.procedure_id
join dbo.T_CON_DISPATCHER_EVENT_TRACK as t
on t.procedure_id = f.procedure_id
where
CAST( f.creation_datetime AS DATE ) > DATEADD( DAY, -14, CAST( GETDATE()
AS DATE))
and
CAST(s.av_summary as NVARCHAR(MAX)) like '%This suggests the stenosis is%'
and
LEN(LTRIM(RTRIM(t.patient_mrn))) > 0
I need to add a column that will pull the study prior to the most
recent study no matter how long ago the previous study was performed.
Add the column as a subquery that gets the TOP 1 date before the date of the current row's study.
I was finally able to figure out how to get the data I wanted for the previous study. I had to correlate the subquery on a couple different columns and I used a completely different table. The database I am working with is a complete mess, but I managed to figure it out. The company that created the database couldn't even figure it out. Thank you all for your help on this. It is much appreciated.
,(select TOP 1 (p1.performed_start_time)
from dbo.T_TCS_PROCEDURE as p1
where
p1.patient_id = p.patient_id
and
p1.performed_start_time < p.performed_start_time
and
p1.procedure_type_id = p.procedure_type_id
order by p1.performed_start_time DESC
) as Last_Echo

SQL Server 2014 Management Studio

I'm a non profit lawyer trying to set up a SQL Server database for my agency. The issue I'm having is query based: I need a simple query that will aggregate the total number of rows on a table, not the sum of the cell contents.
I working with 4 columns of I to: attorney's name, client name, trial date and remedy (the last 2 are date and dollar amount, so integers].
*** Script for SelectTopNRows command from SSMS***
SELECT TOP 100
[attorney]
,[client]
,[trial_date]
,[remedy]
FROM [MyLegalDB]
WHERE [trial_date] between '20160101' and '20160531'
I'm trying to find a way (script, batch file, etc) that will populate a total number of cases by month (according to trial date) total number of clients, and sum the remedy column.
Sorry for the vagueness. There are privilege rules in place. Hope that helps clarify.
Thanks
Assuming that your case history spans years, not just months, try this:
SELECT
,YEAR([trial_date]) AS [Year]
,MONTH([trial_date]) AS [Month]
,COUNT(1) AS [Trial_Count]
FROM [MyLegalDB]
WHERE [trial_date] between '20160101' and '20160531'
GROUP BY YEAR([trial_date]), MONTH([trial_date])
If you want to separate this by attorney, you would need to add that column to the SELECT list, as well as the GROUP BY clause, as such:
SELECT
[attorney]
,YEAR([trial_date]) AS [Year]
,MONTH([trial_date]) AS [Month]
,COUNT(1) AS [Trial_Count]
FROM [MyLegalDB]
WHERE [trial_date] between '20160101' and '20160531'
GROUP BY [attorney], YEAR([trial_date]), MONTH([trial_date])
This is a very general answer to a very general question. If you want me to be more specific, I'm going to have to understand your goal a little better. Hope it helps.

tsql intesect between 2 datetime recordsets

I have an appointments table with appointments for a number of 'resources'
what i need to do is query that and return (for a particular resource) all free appointment slots across a date range.
i had thought the best way to approach this would be to generate a temp table of possible appointment times (as the length of appointment may be 30/60/90 minutes - the appointment length would be specified for the query.) and then select the intersect of those two recordsets. i.e. all of those - across the date range - where there are NOT appointments in the appointments table. thus returning all possible appointments for that resource.
or maybe just - again - generate the records of possible appointment datetimes, and then except the actual appointments already booked..?
unless of course someone can suggest an easier option.?
also not entirely sure how to generate the table of possibles ie a table with records for 2010-12-08 09:00, 2010-12-08 10:00, and so on (for 1 hr appointments)...
any ideas?
edit: have a vague idea on the possibles...
DECLARE #startDate DateTime
DECLARE #EndDate DateTime
set #startDate = '2010-12-08 09:00'
set #endDate = '2010-12-11 09:00';
with mycte as
(
select cast(#startDate as datetime) DateValue
union all
select dateadd(mi,30,DateValue)
from mycte
where DateValue <= #endDate
and datepart(hh, dateadd(mi,30,DateValue)) Between 9 AND 16
)
select DateValue
from mycte
This is a classic gaps and islands problem. It essentially a common problem where you need to identify missing values (gaps) in a sequence. Fortunately there is a free sample chapter on this very topic from the Manning book, SQL Server MVP Deep Dives. Hopefully it will provide inspiration as it gives guidance on a number of possible approaches.
http://www.manning.com/nielsen/SampleChapter5.pdf
Here is Itzik Ben-Gan's description of the problem, quoted from the above chapter.
Gaps and islands problems involve
missing values in a sequence
... The sequences involved can also
be temporal, such as order dates, some
of which are missing due to inactive
periods (weekends, holidays). Finding
periods of inactivity is an example of
the gaps problem, and finding periods
of activity is an example of the
islands problem.

Return a Table of Payroll Dates from a SQL Stored Procedure

I'm working with SQL Server Reporting Services 2008, which is somewhat new to me, as most of my experience is with LAMP development. In addition, moving most of the logic to SQL as stored procedures is something I'm not very familiar with, but would like to do. Any help or direction would be greatly appreciated.
I need a list of acceptable payroll dates in the form of a table to use as the allowed values for a report parameter. Ideally, the person will be able to select this payroll date from the drop-down provided by the report parameter, which will then be used in the dataset to pull data from a table. I would like the logic to be stored on the SQL server if possible, as this is something that will most likely be used on a few other reports.
The logic to create the list of dates is rather simple. It starts with the oldest payroll date that is need by the system (sometime in 2007) and simply goes every two weeks from there. The procedure or function should return a table that contains all these dates up to and including the nearest upcoming payroll date.
It seems to me that the way to go about this would be a procedure or function that creates a temporary table, adds to it the list of dates, and then returns this table so that the report parameter can read it. Is this an acceptable way to go about it?
Any ideas, examples, or thoughts would be greatly appreciated.
I would use a CTE something like this one:
;WITH PayPeriod AS (
SELECT #DateIn2007 AS p UNION ALL
SELECT DATEADD(dd, 14, p) as P FROM PayPeriod WHERE p < GetDate() )
SELECT p FROM PayPeriod
OPTION ( MAXRECURSION 500 )
The MAXRECURSION and/or where parameter limits the number of dates it will generate.
You can use a parameter to figure out the correct limit to get the correct last date still, of course.
try something like this:
;with AllDates AS
(
SELECT CONVERT(datetime,'1/1/2007') AS DateOf
UNION ALL
SELECT DateOf+14
FROM AllDates
WHERE DateOf<GETDATE()+14
)
SELECT * FROM AllDates
OPTION (MAXRECURSION 500)
you can put this in a view or function.
However, I would suggest that instead of presenting a select box of this many values, why not just have two text box fields: start date and end date and default them to reasonable values, just my 2 cents

SSAS - Facts that happened over a time range

I don't really know how to handle facts that happened over a period of time. I sually deal with facts that happened on a specific date.
In clear, my facts have a start_date and an end_date. So, let's say my start_date is 01/01/2008 and my end_date is 01/01/2011. I need to get the number of those facts that happened in 2009 and those that happened this year. The same fact can have happened on both years. The way to determine a fact is part of 2009 is to check for 12/31/2009.
I was thinking about a StartDate and EndDate dimensions, using date ranges (so from the first date of my StartDate dimension to 12/31/2009 and from 12/31/2009 to the last date in my EndDate dimension). I would cross join those.
I tried it, it works, but it's REALLY slow.
Any thoughts?
I found the solution to what I wanted. David and Chris for the anwsers tho! Here's what I wanted to achieve, but I was lacking MDX syntax :
SELECT [Measures].[NumberX] ON COLUMNS
FROM [MyCube]
WHERE ([START DATE].[REFDATE].FirstMember:[START DATE].[REFDATE].&[2009-12-31T00:00:00],
[END DATE].[REFDATE].&[2010-01-01T00:00:00]:[END DATE].[REFDATE].LastMember)
Pretty simple. I think my question was not clear, that's why I got different answers ;-)
You can always use a date range with the two time dimensions like:
Select [start date].[year].[2009]:[end date].[year].[2010] on 0
from cube
If I'm understanding the question correctly. Two time dimensions should work together fine. I have two in a project I'm doing at work and they work rather fast together. Make sure that you set them up in dimension usage section of the cube so you can differentiate the two dates.
You just need one Date dimension DimDate. Your fact table can have 2 foreign keys to the DimDate, one for startdate and one for enddate.
FactTable
{
FactID int,
StartDate int,
EndDate int
-- Other fields
}
DimDate
{
DimDateID int,
Year int,
Month int,
Day int,
-- Other fields if needed
}
To get all facts that fall on the year 2009, use
SELECT f.FactID FROM FactTable f
INNER JOIN DimDate dStart ON dStart.DimDateID = f.StartDate
INNER JOIN DimDate dEnd ON dEnd.DimDateID = f.EndDate
WHERE dStart.Year <= 2009
AND dEnd.Year >= 2009

Resources