getting previous dates for Point in time reporting - sql-server

I need to generate the date of the previous quarter end's date, using a pre-established date field.
ex. It should show 09-30-2022 as that is the monthend date of the previous quarterend.
DECLARE #current_monthend AS VARCHAR(30)
SET #current_monthend = (SELECT max(ver) FROM dbo.vQlik_CRE_Dashboard);
select and from
where
ver = (DATEADD(d, -1, DATEADD(q, DATEDIFF(q, 0, #current_monthend) +1, 0)) ) )
this gets me the current period but not the previous. how do I alter this to get the previous ?

Related

Declaring a date as being the last month day of another date

I'm trying to write a financial report on our SAP B1 system using SQL Server Studio.
In my report I want the information to be calculated on a month to month basis. In my report I have #start date as #Startofcurrentfinancialyear, and my end as DD+30 (because there are 31 days in the month) However I am wanting to have mm+1 and dd-1 to bring me to the last day in the month.
I plan on changing the report for each month to give me the following.
MM+1 (for month 2) and MM+2 - DD 1 to give me the date range for month 2 etc.
Currently, I can make this go based on the following: MM+0, DD+30, then going ahead doing DD+60 etc and calculating for each month how many days they are, but this will give me problems with leap years.
DECLARE #Start DATETIME = DATEADD(MM,-0,#StartOfCurrentFinancialYear)
DECLARE #End DATETIME = DATEADD(DD,+30,#StartOfCurrentFinancialYear)
I expect to be able to define a month for each section and give the last day of the defined month based on the parameters given above.
If you want the end of month, then in all supported versions of SQL Server, you can do:
DECLARE #Start DATETIME = DATEADD(MONTH, -0, #StartOfCurrentFinancialYear);
DECLARE #End DATETIME = EOMONTH(#StartOfCurrentFinancialYear);
If you are using an unsupported version, you can do date arithmetic:
DECLARE #End DATETIME = DATEADD(day, -1,
DATEADD(month, 1,
DATEADD(day,
1 - DAY(#StartOfCurrentFinancialYear),
#StartOfCurrentFinancialYear
),
)
);
This does the following calculation:
Innermost subquery dateadd() moves to the first day of the month.
Middle subquery adds one month.
Outer query subtracts one day.
If you want start of the month and end of the month you can get it by using DateAdd function like :
DECLARE #Start DATETIME = DATEADD(DAY, (DAY(GETDATE()) * -1) + 1, GETDATE())
DECLARE #End DATETIME = DATEADD(MONTH,1,DATEADD(DAY, DAY(GETDATE()) * -1, GETDATE()))
SELECT #Start, #End
you can replace GETDATE() with your date variable so after your replacement the code should be something like this :
DECLARE #StartOfCurrentFinancialYear AS DATE = '31/aug/2019'
DECLARE #Start DATETIME = DATEADD(DAY, (DAY(#StartOfCurrentFinancialYear) * -1) + 1, #StartOfCurrentFinancialYear)
DECLARE #End DATETIME = DATEADD(MONTH,1,DATEADD(DAY, DAY(#StartOfCurrentFinancialYear) * -1, #StartOfCurrentFinancialYear))
SELECT #Start, #End

Write a single query to search between two dates and when To date is not available then it should search greater then first date

Write a single query to search between two dates and when To date is not available then it should search greater then first date.
For example: search between two dates, when both from and to dates are available
11-10-2015 to 11-10-2017
My query should also return result when To date is not available
For example: I want to write single query without any if and else
This code works and it is a single statement, as requested.
SELECT * from MyTable WHERE recordingdate BETWEEN COALESCE(#startdate,CAST('01/01/1753 00:00:00.000' AS DATETIME)) AND COALESCE(#enddate,CAST('12/31/9999 23:59:59.997' AS DATETIME))
If the start date is NULL, COALESCE will return the minimum date value, as defined by SQL Server. Otherwise, it returns the start date value sent in.
If the end date is NULL, COALESCE will return the maximum date value, as defined by SQL Server. Otherwise, it returns the end date sent in.
Feel free to turn the COALESCE statements for MIN and MAX possible dates into functions, as SQL Server does not have built-in functions for minimum and maximum possible dates.
Writing your code this way allows you to always execute a BETWEEN.
Try Thie below Logic
DECLARE #FromDt DATE='01/01/2017',#ToDate DATE = NULL
SELECT
*
FROM YourTable
WHERE FromDate > #FromDate
AND
(
#ToDate IS NULL
OR
(
#ToDate IS NOT NULL
AND
ToDate > #ToDate
)
)
declare #dt_from date = '20151011',
#dt_to date = '20171011' -- null
select *
from dbo.your_table
where date_field >= #dt_from and data <= isnull(#dt_to, '99990101');

Automate an SSIS query for a table name having a month and year timestamp

I have a database in which a table names are associated with month and year numbers ex: datavalues_7_2017 for july, datavalues_8_2017 for august and so on.
I am using a query to retrieve certain values from the table.
SELECT o_key ,MIN(dateadd(hour, datediff(hour, 0, time), 0)) as on_time
,MAX(dateadd(hour, datediff(hour, 0, dateadd(hour, 1, time)), 0)) as off_time
,cast(time as date) as RDNG_DT ,[repeated_hour],[value]
FROM [data_values_8_2017]
WHERE value = 1 and o_key in (X,X,X,X...) and cast(time as date) = cast(getdate() as date)
GROUP BY o_key,cast(time as date),repeated_hour,value
I am using SSIS package and using this query I am loading the result into another table.
Now this table datavalues_X_2017 is bound to change every month creating a new table, and my SSIS query should be pointing to the new table.
Can someone suggest me a way where I can automate this processes.
All you need to do is create a stored procedure as a wrapper and have a date parameter passed to it as shown below. Call this procedure as part of your source.
If you do not want it as stored procedure, use the same logic and put the sql as a variable and in the expressions pass the month and year variable
create procedure dbo.usp_GetData
(
#Date datetime = null
)
as
if #Date is null
set #Date = GETDATE()
declare #Month int
,#Year int
,#sql nvarchar(max)
select #Month = DATEPART(MONTH,#Date)
,#Year = DATEPART(YEAR,#Date)
set #sql ='
select o_key
,MIN(dateadd(hour, datediff(hour, 0, time), 0)) as on_time
,MAX(dateadd(hour, datediff(hour, 0, dateadd(hour, 1, time)), 0)) as off_time
,cast(time as date) as RDNG_DT
,[repeated_hour],[value]
from [data_values_'+CAST(#Month AS VARCHAR(2))+'_'+CAST(#Year AS VARCHAR(4))+']
where value = 1
and o_key in (
X,X,X,X...
)
and cast(time as date) = cast(getdate() as date)
group by o_key
,cast(time as date)
,repeated_hour
,value
';
exec sp_executesql #sql;
go
Get dynamic SQL with Variable Expressions the following way:
Create a String variable DateSuffux which will be filled with your datevalue like "7_2017"
Create a String variable SQLQuery with properties EvaluateAsExpression=true and define the following Expression for it
"SELECT o_key ,...,[repeated_hour],[value] FROM [data_values_" +
#[User::DateSuffix] + "] WHERE ... "
Specify variable SQLQuery as a source for your Data Source or SQL Query task
You are done.
This variable expression substitutes result of the expression when the SQLQuery variable is used. The expression itself injects contents of DateSuffix string variable into a query text.

Unique Start and End Effective Date Scenario

Okay, so I have an sql query that I run on a weekly basis that now needs to be ran on a monthly basis. In the query I have a start effective date and an end effective date for the date range the report should pull. Now what I want to do is a formula for the start and end date.
The start effective date I want to be previous month from today's date and then the last Monday of the previous month.
The end effective date I want to be the max modified date from my product details table.
I know what I am looking for but I am unsure how to write this in code? Thanks!!!
This should do the trick:
DECLARE #Today date = convert(date, getdate());
DECLARE #Monday tinyint = 1;
DECLARE #LastDayOfMonth date = DATEADD(d,-1,DATEADD(month, DATEDIFF(month, 0, #Today), 0));
DECLARE #LastWeekDayOfMonth int = datepart(weekday,DATEADD(d,-1,DATEADD(month, DATEDIFF(month, 0, #Today), 0)));
SELECT DATEADD(d, #Monday-#LastWeekDayOfMonth+1, #LastDayOfMonth) AS LastMonday
try this
declare #dt datetime
set #dt=GETDATE()
select DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,DATEPART(DAY,dateadd(m,-1,GETDATE())),dateadd(m,-1,GETDATE()))), 0) StartDate

Date Exists between Range of Dates not working

ALTER PROCEDURE [dbo].[spInsert]
(#PlanName Varchar(50)=null
,#StartDate Datetime
,#EndDate Datetime
,#ModifiedBy Varchar(100)=null
,#ReturnValue Int Out)
As
BEGIN
IF NOT EXISTS(SELECT PlanName FROM dbo.tblPlan WHERE PlanName=#PlanName)
BEGIN
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate <=
#EndDate)<0)
BEGIN
INSERT INTO dbo.tblPlan VALUES(3,#PlanName,#StartDate,#EndDate,#ModifiedBy,GETDATE(),
(SELECT DATEDIFF(DD,#StartDate,#EndDate)))
SET #ReturnValue=1;
END
ELSE
SET #ReturnValue=-2;
END
ELSE
SET #ReturnValue=-1;
END
I am trying to achieve the below thing.I want to check user supplied startDate and Enddate is in between the existing table startdate and enddate. if any of the date of user supplied date range is in between the tables start date and end date,it should return -2,if the record does not exists it should insert the details..
I Could not achieve this logic.where i went wrong ..please suggest me any solution to this.
EDIT:First Consditon check whether planName is exists or not,If not exists then want to check Start and End Date already existed or Not(Including start and End)
I tried two ways as suggested mentioned in the replies.
eg:If existing start and end range is Start-2013-10-09,End-2013-10-15,If am going to insert another plan then the start and end date of this plan should not fall between 9th-15th october and start and End date should not be 9th or 15 th both.
ONE:IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate <=
#EndDate)=0)
Result: It does not insert any data, even it is out of previous date. or with in the
range
SECOND:IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate>=#StartDate AND
EndDate<=#EndDate)=0)
RESULT: It insert the date with out Considering the above condition.
I think you need to change your if from
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate <= #EndDate)<0)
to
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate >= #EndDate)=0)
Which should ensure that #StartDate and #EndDate is between StartDate and EndDate and test for =0
COUNT(*) can never be smaller than zero like your code suggests.
It's either a positive integer (which is greater than zero), or null, which will also return false on any arithmetic condition.
try the below :
ALTER PROCEDURE [dbo].[spInsert]
(#PlanName Varchar(50)=null
,#StartDate Datetime
,#EndDate Datetime
,#ModifiedBy Varchar(100)=null
,#ReturnValue Int Out)
As
BEGIN
IF NOT EXISTS(SELECT PlanName FROM dbo.tblPlan WHERE PlanName=#PlanName)
BEGIN
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate >= #StartDate AND EndDate <=
#EndDate)=0)
BEGIN INSERT INTO dbo.tblPlan
VALUES(3,#PlanName,#StartDate,#EndDate,#ModifiedBy,GETDATE(),
(SELECT DATEDIFF(DD,#StartDate,#EndDate)))
SET #ReturnValue=1;
END
ELSE
SET #ReturnValue=-2;
END
ELSE
SET #ReturnValue=-1;
END
As count always return positive value or zero. so your first condition always being false.
*UPDATE:*
you want to say if Sdate is '12-12-2013' and edate is '15-12-2013' then you don't want to considers these dates in check if so then try replace the query with below:
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate > #StartDate AND EndDate <
#EndDate)=0)
If you're wanting to check whether the period defined by #StartDate,#EndDate overlaps with any period defined by the values in the StartDate,EndDate columns for a particular row, then the actual comparison that you want to perform is:
StartDate < #EndDate AND EndDate < #StartDate
(With appropriate adjustments of < to <= depending on whether you want to consider two periods such that one starts at the exact time that the other finishes as overlapping or not)
The logic is - Two periods overlap if both of the following conditions are true:
period 1 starts before period 2 ends
period 2 starts before period 1 ends
Other notes -
A COUNT will never be <0 so that part of the logic is incorrect. If you merely want to determine whether any rows exists, use EXISTS (as you already have once) - don't force a COUNT if you don't actually need to know how many rows match your criteria.
I also find it slightly suspect that your first query considers PlanName but your second doesn't. Are you sure that this is correct?

Resources