Monthly wise count using date calculation - sql

I have the table named company with columns company name, create date, etc.
I want to get the count of companies created for this month.
I have the stored procedure for weekly wise count
CREATE PROCEDURE [dbo].[pr_NewCmpCount]
#StartDate DATETIME = NULL --'20130508'
, #EndDate DATETIME = NULL --'20130515'
AS
BEGIN
DECLARE #DateDiff INT
, #MainDate DATETIME
IF #StartDate IS NULL AND #EndDate IS NULL
BEGIN
IF (DATEPART(dw,GETDATE()) > 3)
SET #DateDiff = 0
ELSE
SET #DateDiff = 6
SET #MainDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,#DateDiff,GETDATE()), 0)))
SELECT #StartDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,0,#MainDate), -5)))
SELECT #EndDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,0,#MainDate), 2)))
SELECT CONVERT (VARCHAR, Count(*)) AS [Count]
, CONVERT (DATE, DATEADD (DD, 1, #StartDate)) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
FROM
Company WITH(NOLOCK)
WHERE CreateDate >= #StartDate
AND CreateDate < #EndDate
END
ELSE
IF ((CONVERT (DATE, #StartDate) < CONVERT (DATE, #EndDate)) AND (CONVERT (DATE, #EndDate) < CONVERT (DATE, GETDATE())))
BEGIN
SET #StartDate = CONVERT (DATE, #StartDate)
SET #EndDate = CONVERT (DATE, #EndDate)
SELECT #StartDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, #StartDate))
SELECT #EndDate = DATEADD (MINUTE, 30, DATEADD (HOUR, 18, #EndDate))
SELECT CONVERT (VARCHAR, Count(*)) AS [Count]
, CONVERT (DATE, DATEADD (DD, 1, #StartDate)) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
FROM
Company WITH(NOLOCK)
WHERE CreateDate >= #StartDate
AND CreateDate < #EndDate
END
ELSE
SELECT 'Please Run After Tuesday of Every Week or Given the Valid Date' [Count]
, CONVERT (DATE, #StartDate) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
END
Output for this stored procedure is
Count Startdate EndDate
10 2016-03-13 2016-03-22
Expected output
Count Startdate EndDate
20 2016-02-01 2016-02-29
Where do I need to modify in my stored procedure to get monthly wise count?

Something like this:
DECLARE #StartDt Date
DECLARE #EndDt date
SELECT #StartDt,#EndDt,Count(*) AS TotalCompanies FROM company
WHERE [create date] BETWEEN #StartDt AND #EndDt
I skipped the stored procedure formatting for simplicity.

Related

DateDiff In months between two different types date formats

I have two date formats, EndDate in YYYYMMDD format and another Monthfirstdate in YYYY-MM-DD FORMAT. I need to get the difference between these two dates.
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #Date DATE = dbo.value('DATE')
SELECT
E.EmployeeID
,E.StartDateKey
,E.EndDateKey
,E.FromDateKey
,E.ToDateKey
INTO #Employee
FROM
dbo.Employee E
---clean--
DECLARE #StartDate DATE = (SELECT DATEADD(YY, DATEDIFF(YY, 0, #Date) - 1, 0))
DECLARE #EndDate DATE = DATEADD(S, -1, DATEADD(MM, DATEDIFF(MM, 0, #Date) + 3, 0))
SELECT
E.EmployeeID
,CAST(CONVERT(VARCHAR(10), E.StartDateKey, 112) AS INT) AS _EmployeeStartDateKey
,CAST(CONVERT(VARCHAR(10), E.EndDateKey, 112) AS INT) AS _EmployeeFinishDateKey
,CAST(CONVERT(VARCHAR, D.MonthFirstDay, 112) AS INT) AS _DateKey
,???? AS [Tenure]
FROM #Employee AS E
INNER JOIN dbo.Date D ON
D.DateKey BETWEEN E.FromDateKey AND E.ToDateKey
WHERE
D.DateKey BETWEEN #tartDate AND #EndDate
AND D.DayOfMonth = 1
You can try below query in SQL Server:
DECLARE
#firstDate DATETIME = '2022-12-01',
#dateinStringFormat VARCHAR(20)= '20121201',
#endDate DATETIME;
--Converting date string to Datetime format(YYYY-MM-DD)
SELECT #endDate = CONVERT(CHAR(10), CONVERT(datetime, #dateinStringFormat), 120);
--Now, Calculating the date difference in Month
SELECT DATEDIFF(MONTH, #endDate, #firstDate) AS DateDiff;

How to calculate difference between two dates in seconds during business hours for business days SQL Server?

I like to get the difference in seconds between two working days in SQL Server. We have date table contains IsWorkingDay flag, if the end date is null then it should default to getdate(). The workday starts at 8 am and finishes at 4:30 pm.
I have the following query, need help in else part.
#StartDate and #EndDate will not always be on workdays. If #StartDate is on any weekend or Holiday, it should roll up to Next working day at 8:00 am. If #EndDate is on any weekend or Holiday, it should roll up to last working day at 4:30 pm.
CREATE FUNCTION TimeDiffInSeconds
(
#Startdate DATETIME
,#EndDate DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE #WorkSeconds INT = 0;
DECLARE #Reverse BIT;
DECLARE #StartHour FLOAT = 8
DECLARE #EndHour FLOAT = 16.50
IF #Startdate > #EndDate
BEGIN
DECLARE #TempDate DATETIME = #Startdate;
SET #Startdate = #EndDate;
SET #EndDate = #TempDate;
SET #Reverse = 1;
END;
ELSE
SET #Reverse = 0;
IF DATEPART(HH, #StartDate) < #StartHour
SET #StartDate = DATEADD(HOUR, #StartHour, DATEDIFF(DAY, 0, #StartDate));
IF DATEPART(HH, #StartDate) >= #EndHour + 1
SET #StartDate = DATEADD(HOUR, #StartHour + 24, DATEDIFF(DAY, 0, #StartDate));
IF DATEPART(HH, #EndDate) >= #EndHour + 1
SET #EndDate = DATEADD(HOUR, #EndHour, DATEDIFF(DAY, 0, #EndDate));
IF DATEPART(HH, #EndDate) < #StartHour
SET #EndDate = DATEADD(HOUR, #EndHour - 24, DATEDIFF(DAY, 0, #EndDate));
IF #Startdate > #EndDate
RETURN 0;
IF DATEDIFF(DAY, #StartDate, #EndDate) <= 0
BEGIN
IF #Startdate <> (SELECT date_id FROM Final.Date WHERE IsWorkingDay = 0)
SET #WorkSeconds = DATEDIFF(ss, #StartDate, #EndDate); -- Calculate difference
ELSE RETURN 0;
END;
ELSE
--need help
RETURN #WorkSeconds;
END
It can be calculated in a simple way.
If your two parameters are already working days then you can just return their difference in seconds, minus 15.5 hours (16:30 to 08:00) for every day difference (every time the midnight boundary is crossed), minus 8,5 hours (8:00 to 16:30) for every not working day between your two dates.
PS: I have updated the answer, so we now first check if #StartDate and #EndDate are correct working datetimes, and if not then we move them to the correct ones. After that you can apply the previously described calculation for the working time in seconds.
CREATE FUNCTION TimeDiffInSeconds
(
#Startdate datetime,
#EndDate datetime
)
RETURNS INT
AS
BEGIN
set #EndDate = coalesce(#EndDate, getdate());
-- We check that #StartDate is a working datetime, and if not we set it to the next one
if convert(time, #StartDate) < convert(time, '08:00')
begin
set #StartDate = convert(datetime, convert(date, #StartDate)) +
convert(datetime, '08:00')
end
if convert(time, #StartDate) > convert(time, '16:30') or
(select IsWorkingDay
from Final.Date
where date_id = convert(date, #StartDate)) = 0
begin
select top 1 #StartDate = convert(datetime, date_id) +
convert(datetime, '08:00')
from Final.Date
where date_id > #StartDate and IsWorkingDay = 1
order by date_id
end
-- We check that #EndDate is a working datetime, and if not we set it to the last one
if convert(time, #EndDate) > convert(time, '16:30')
begin
set #EndDate = convert(datetime, convert(date, #EndDate)) +
convert(datetime, '16:30')
end
if convert(time, #EndDate) < convert(time, '08:00') or
(select IsWorkingDay
from Final.Date
where date_id = convert(date, #EndDate)) = 0
begin
select top 1 #EndDate = convert(datetime, date_id) +
convert(datetime, '16:30')
from Final.Date
where date_id < #EndDate and IsWorkingDay = 1
order by date_id desc
end
-- We return the working time difference in seconds between #StartDate and #EndDate
RETURN datediff(second, #StartDate, #EndDate) -
((15.5 * datediff(day, #StartDate, #EndDate) * 60 * 60) -
(8.5 * (select count(*)
from Final.Date
where IsWorkingDay = 0 and
(date_id between #StartDate and #EndDate or date_id between #EndDate and #StartDate)
) * 60 * 60));
END
Test online: https://rextester.com/FWR14059

SQL Server 2014 - How to get date range of 7 days ago plus 1 hour

I need to pull up details from 1 hour past midnight, 7 days ago. But I'm not getting the results I need.
My code:
SELECT *
FROM Table
WHERE BusinessDay >= DateAdd(HOUR, 1, (DateAdd(DAY, -7, getdate()))) --#StartDate
AND BusinessDay <= DateAdd(HOUR, 1, getdate()) --#EndDate
When I give an actual time like below, I get the results I need:
WHERE BusinessDay >= '2018-04-04 00:01:000' --#StartDate
AND BusinessDay <= '2018-04-11 00:01:000' --#EndDate
I need to pass the dates in a parameters in SSRS. But clearly, the syntax is wrong in SSRS too.
I tried the below code but I get an error message:
WHERE BusinessDay >= DateAdd(HOUR, 1, (DateAdd(DAY, -7, CAST(getdate() as date)))) --#StartDate
AND BusinessDay <= DateAdd(HOUR, 1, CAST(getdate() as date)) --#EndDate
The error message: The datepart hour is not supported by date function dateadd for data type date.
So, I also tried the below code but got no results:
WHERE BusinessDay >= DateAdd(HOUR, 1, (DateAdd(DAY, -7, CAST(CAST(GETDATE() AS DATE) AS DATETIME)))) --#StartDate
AND BusinessDay <= DateAdd(HOUR, 1, CAST(CAST(GETDATE() AS DATE) AS DATETIME)) --#EndDate
Try this:
SELECT DATEADD(HH, 1, FORMAT(DATEADD(DD, -7, CAST(GETDATE() AS DATE)), N'yyyy-MM-dd HH:00:000'))
SQL Server 2014 introduced the FORMAT() function to make it easier to return/display data types in a formatting that you want without having to do a whole bunch of math with the formulas. Note: the format pattern is case-sensitive.
GETDATE() = '2018-04-11 18:20:00.000'
Formula Result: '2018-04-04 01:00:00.000'
For more information on the FORMAT() function, see here: https://learn.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql
With a little tweak to Gordon's answer to avoid an error produced by doing a CAST within the DATEADD function:
DECLARE #td DATETIME = CAST (GETDATE() AS DATE);
DECLARE #td1AM DATETIME = DATEADD(HOUR, 1, #td);
DECLARE #weekAgo1AM DATETIME = DATEADD(DAY, -7, #td1AM);
Then do your query with this:
SELECT *
FROM Table
WHERE BusinessDay >= #weekAgo1Am -- #StartDate
AND BusinessDay <= #td1AM -- #EndDate
For SSRS, via the answer linked in your comments, use TODAY():
DECLARE #td DATETIME = TODAY();
DECLARE #td1AM DATETIME = DATEADD(HOUR, 1, #td);
DECLARE #weekAgo1AM DATETIME = DATEADD(DAY, -7, #td1AM);
And the same query:
SELECT *
FROM Table
WHERE BusinessDay >= #weekAgo1Am -- #StartDate
AND BusinessDay <= #td1AM -- #EndDate
getdate() has a time component. So, remove it first:
WHERE BusinessDay >= DateAdd(HOUR, 1, (DateAdd(DAY, -7, cast(CAST(getdate() as date) as datetime)))) AND --#StartDate
BusinessDay <= DateAdd(HOUR, 1, cast(CAST(getdate() as date) as datetime)) --#EndDate

Find the Same day of Previous Year Given by Current Year Date in SQL Server

I am working with SQL Server, The scenario is to find out the Same Day's Date of Previous Year as of Today's Day.
Suppose 2014-03-06 is Today Date and Day is Thursday I want to Find the Same day in Previous lies in the same week .which is 2013-03-07
can any body help?
HERE is what i Have Written:
DECLARE #DateFrom AS DATETIME
DECLARE #DateTo AS DATETIME
SET #DateFrom = '2014-01-01'
SET #DateTo = '2014-02-10'
DECLARE #Count AS INT
SET #Count = DATEDIFF(DAY, #DateFrom, #DateTo)
CREATE TABLE #current_year /*This Year*/
(
[Date] DATETIME ,
WeekNum INT,
[Day] VARCHAR(20),
Data INT
)
CREATE TABLE #last_year /*This Year -1*/
(
[Date] DATETIME ,
WeekNum INT,
[Day] VARCHAR(20),
Data INT
)
WHILE ( #Count > 0 )
BEGIN
INSERT INTO #current_year
VALUES ( CONVERT(VARCHAR(10), #DateFrom, 101),
DATEPART(week,#DateFrom),
DATENAME(weekday, #DateFrom),#Count)
INSERT INTO #last_year
VALUES ( CONVERT(VARCHAR(10), DATEADD(YEAR, -1, #DateFrom), 101),
DATEPART(week,DATEADD(YEAR,1,#DateFrom)),
DATENAME(weekday, DATEADD(YEAR, -1, #DateFrom)),#Count)
SET #DateFrom = DATEADD(day, 1, #DateFrom)
SET #Count = #Count - 1
END
SELECT * from #current_year
SELECT * from #last_year
SELECT CONVERT(varchar(10),#current_year.[Date],111) AS CYDate,
--ISNULL(CONVERT(varchar(10),#last_year.[Date],111) ,/*CONVERT(varchar(10),DateAdd(dd, 1, DATEADD(yy, -1, #current_year.Date)),111)*/) AS LYDate
--CONVERT(varchar(10),#last_year.[Date],111) AS LYDate
Coalesce(CONVERT(varchar(10),#last_year.[Date],111) ,DateAdd(dd, 1, DATEADD(yy, -1, #current_year.Date))) AS LYDate,
#current_year.Data AS CD,
#last_year.Data AS LD
FROM #current_year
--LEFT JOIN #last_year ON #last_year.WeekNum = #current_year.WeekNum
-- AND #last_year.[Day] = #current_year.[Day]
Left JOIN #last_year ON #last_year.WeekNum = DatePart(wk, GETDATE())
DROP TABLE #current_year
DROP TABLE #last_year
Here is the Output:
Here is the output after adding your solution, now in left join it excludes (NULL) data of previous year
Basically you need to find difference in days between same dates in this and previous years, then understand "day difference" by mod 7, and sum it with date in previous year:
DECLARE #now DATETIME
SET #now = '2014-03-06'
SELECT CAST (DATEADD(YEAR, -1, #now) + (CAST (#now as INT) - CAST (DATEADD(YEAR, -1, #now) AS INT)) % 7 AS DATE)
Returns
2013-03-07
Try
DECLARE #now Date
SET #now = '2014-06-03'
SELECT DATEADD(week, -52, #now)
SELECT DateName(dw, DATEADD(yy, -1, GETDATE()))
gives Wednesday
SELECT DateName(dw, DateAdd(dd, 1, DATEADD(yy, -1, GETDATE())))
gives Thursday
edit:
SELECT DateAdd(dd, 1, DATEADD(yy, -1, GETDATE()))
gives '2013-03-07 17:30:16.590'
you need to cast the date as per you requirement..
update:
change this part with,
Left JOIN #last_year ON #last_year.WeekNum = DatePart(wk, GETDATE())
in your case:
Left JOIN #last_year ON DatePart(wk, #last_year.[Date]) = DatePart(wk, #current_year.[Date])
update 2:
Left JOIN #last_year ON (MONTH(#last_year.[Date])=MONTH(#current_year.[Date]) and Day(#last_year.[Date])=Day(#current_year.[Date]))
Output:
or
output:
Left JOIN #last_year ON (#last_year.WeekNum = #current_year.WeekNum and #last_year.[Day] = #current_year.[Day])
choose which ever is your required output.
DECLARE #Date DATE = '2014-03-06'
SELECT DATEADD(WEEK,-52,#Date)
Retrun value :
2013-03-07

Compare current date with stored datetime using month an year only

Using SQL Server 2005 I have a field that contains a datetime value.
What I am trying to do is create 2 queries:
Compare to see if stored datetime is of the same month+year as current date
Compare to see if stored datetime is of the same year as current date
There is probably a simple solution but I keep hitting brick walls using various samples I can find, any thoughts?
Thanks in advance.
Compare the parts of the date:
WHERE YEAR( columnName ) = YEAR( getDate() )
While the other answers will work, they all suffer from the same problem: they apply a transformation to the column and therefore will never utilize an index on that column.
To search the date without a transformation, you need a couple built-in functions and some math. Example below:
--create a table to hold our example values
create table #DateSearch
(
TheDate datetime not null
)
insert into #DateSearch (TheDate)
--today
select getdate()
union all
--a month in advance
select dateadd(month, 1, getdate())
union all
--a year in advance
select dateadd(year, 1, getdate())
go
--declare variables to make things a little easier to see
declare #StartDate datetime, #EndDate datetime
--search for "same month+year as current date"
select #StartDate = dateadd(month, datediff(month, 0, getdate()), 0), #EndDate = dateadd(month, datediff(month, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
--search for "same year as current date"
select #StartDate = dateadd(year, datediff(year, 0, getdate()), 0), #EndDate = dateadd(year, datediff(year, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
What the statement does to avoid the transformations, is find all values greater-than or equal-to the beginning of the current time period (month or year) AND all values less-than the beginning of the next (invalid) time period. This solves our index problem and also mitigates any issues related to 3ms rounding in the DATETIME type.
SELECT * FROM atable
WHERE
YEAR( adate ) = YEAR( GETDATE() )
AND
MONTH( adate ) = MONTH( GETDATE() )
It sounds to me like DATEDIFF is exactly what you need:
-- #1 same month and year
SELECT *
FROM your_table
WHERE DATEDIFF(month, your_column, GETDATE()) = 0
-- #2 same year
SELECT *
FROM your_table
WHERE DATEDIFF(year, your_column, GETDATE()) = 0
The datepart function lets you pull the bits you need:
declare #d1 as datetime
declare #d2 as datetime
if datepart(yy, #d1) = datepart(yy, #d2) and datepart(mm, #d1) = datepart(mm, #d2) begin
print 'same'
end
You can use something like this
a)
select *
from table
where MONTH(field) = MONTH(GetDATE())
and YEAR(field) = YEAR(GetDATE())
b)
select *
from table
where YEAR(field) = YEAR(GetDATE())