SQL Same Colum for differnet date - sql

Look for some assistance. I want to query in one result comparison from one column comparing year results.
I can get it fine with 2 selects as follows, but not one. ANy thoughts?
DECLARE #CYBeginDate datetime
, #CYEndDate datetime
, #LYBeginDate datetime
, #LYEndDate datetime
, #2YBeginDate datetime
, #2YEndDate datetime
select #CYBeginDate = dateadd(year, datepart(year, getdate()) - 1900, '1900-07-01')
select #CYEndDate = dateadd(day, -1, dateadd(month, 12, #CYBeginDate))
select #LYBeginDate = dateadd(year, -1, #CYBeginDate)
select #LYEndDate = dateadd(year, -1, #CYEndDate)
select #2YBeginDate = dateadd(year, -2, #CYBeginDate)
select #2YEndDate = dateadd(year, -2, #CYEndDate)
Select ClientName, ClassOfRiskname, SUM([GrossEarningsNetGST]) AS 'This Year Earnings', NUll
from Reports_Policy_Transactions
where EffectiveDate between #CYBeginDate and #CYEndDate
AND ClientId = 77942
Group By ClientName, ClassOfRiskname
Select Null, Null, Null, SUM([GrossEarningsNetGST]) AS 'Last Year Earnings'
from Reports_Policy_Transactions
where EffectiveDate between #LYBeginDate and #LYEndDate
AND ClientId = 77942
Group By ClientName, ClassOfRiskname

not sure what does second select mean by all null values , but here is how you can merge two queries, but it really depends on your data , It might not work for your data and you might still need to keep where clause with dates and combine them using or
Select ClientName
, ClassOfRiskname
, SUM(case when EffectiveDate between #LYBeginDate and #LYEndDate then [GrossEarningsNetGST] else 0 end ) AS 'This Year Earnings'
, SUM(case when EffectiveDate between #CYBeginDate and #CYEndDate then [GrossEarningsNetGST] else 0 end ) AS 'Last Year Earnings'
from Reports_Policy_Transactions
where ClientId = 77942
Group By ClientName, ClassOfRiskname

Related

my end goal is to see end of month data for previous month

My end goal is to see end of month data for previous month.
Our processing is a day behind so if today is 7/28/2021 our Process date is 7/27/2021
So, I want my data to be grouped.
DECLARE
#ProcessDate INT
SET #ProcessDate = (SELECT [PrevMonthEnddatekey] FROM dbo.dimdate WHERE datekey = (SELECT [datekey] FROM sometable [vwProcessDate]))
SELECT
ProcessDate
, LoanOrigRiskGrade
,SUM(LoanOriginalBalance) AS LoanOrigBalance
,Count(LoanID) as CountofLoanID
FROM SomeTable
WHERE
ProcessDate in (20210131, 20210228,20210331, 20210430, 20210531, 20210630)
I do not want to hard code these dates into my WHERE statement. I have attached a sample of my results.
I am GROUPING BY ProcessDate, LoanOrigRiskGrade
Then ORDERING BY ProcessDate, LoanOrigIRskGrade
It looks like you want the last day of the month for months within a specified range. You can parameterize that.
For SQL Server:
DECLARE #ProcessDate INT
SET #ProcessDate = (
SELECT [PrevMonthEnddatekey]
FROM dbo.dimdate
WHERE datekey = (
SELECT [datekey]
FROM sometable [vwProcessDate]
)
)
DECLARE #startDate DATE
DECLARE #endDate DATE
SET #startDate = '2021-01-01'
SET #endDate = '2021-06-30'
;
with d (dt, eom) as (
select #startDate
, convert(int, replace(convert(varchar(10), eomonth(#startDate), 102), '.', ''))
union all
select dateadd(month, 1, dt)
, eomonth(dateadd(month, 1, dt))
from d
where dateadd(month, 1, dt) < #endDate
)
SELECT ProcessDate
, LoanOrigRiskGrade
, SUM(LoanOriginalBalance) AS LoanOrigBalance
, Count(LoanID) as CountofLoanID
FROM SomeTable
inner join d on d.eom = SomeTable.ProcessDate
Difficult to check without sample data.

How to convert month to week to this query

;With CTE_Mem as (
Select m.PeopleID , m.Operator, m.LocationName,
sum(case when M.ActiveStart < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0) AND M.ActiveEnd
> DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0) then 1 else 0 end) as No_of_Live_Member ,
sum(case when M.ActiveEnd BETWEEN DATEADD(month, DATEDIFF(month, 0, GETDATE()) - 1, 0) and
DATEADD(month, DATEDIFF(MONTH, 0,Getdate()) , -1) then 1 else 0 end) as No_of_Member_Cancelled
From dbo.Memberships m
Group by m.PeopleID , m.Operator, m.LocationName
)
Select * from CTE_Mem
I want to calculate the last month Aug 1st to Aug 31 weeks and convert the above query month to week and shows also which week is?
Please check this for tabular format results:
Format results
I think I know what you are attempting to do, however, you lack details in your schema and there are gaps on how you want to obtain the final results. Here is a basic date math query that partitions date by an id ranked within each month/year combination found in the data. This might help you get from A->B.
DECLARE #T TABLE (ID INT, ActiveStart DATETIME)
INSERT #T VALUES
(1,'08/05/2020'),
(1,'08/10/2020'),
(1,'08/20/2020'),
(2,'08/20/2020'),
(2,'08/20/2021')
;
WITH WeekValuesWithID AS
(
SELECT
ID,
YearNumber = DATEPART(YEAR,ActiveStart),
MonthNumber = DATEPART(MONTH,ActiveStart),
WeekNumberInMonth = RANK() OVER (PARTITION BY DATEPART(YEAR,ActiveStart), DATEPART(MONTH,ActiveStart) ORDER BY DATEPART(WEEK,ActiveStart))
FROM
#T
)
SELECT
IDCount = COUNT(ID),
WeekNumberInMonth,
MonthNumber,
YearNumber
FROM
WeekValuesWithID
GROUP BY
WeekNumberInMonth,
MonthNumber,
YearNumber

SQL Server : CASE-WHEN returns error in select list or Not-exist block if used in both

In the below SQL Server 2008 select statement Case-When is used in 2 places, in the select list and inside NOT EXISTS: CASE-1 and CASE-2.
It works only if I comment out one of case-when statements, only if I use it only in one place: select list OR not-exist.
If it used in both places, as below, I get error:
Conversion failed when converting date and/or time from character string.
I did my research, read http://www.fmsinc.com/free/newtips/sql/sqltip10.asp, but I still can not make it work.
Please help, what is wrong with code below? Thank you
MyTable.dob is nvarchar(10)
PayrollTable.date_of_birth is varchar(10)
Both dob columns are nullable.
MyTable.dob is in format mmddyy like '010255'.
PayrollTable.date_of_birth is in format 'mm/dd/yyyy' like '01/02/1955'
Code:
SELECT
FName,
LName,
( --- CASE-1
select
CASE
WHEN CONVERT(DATE, STUFF(STUFF(a.dob,3,0,'/'),6,0,'/')) > GETDATE()
THEN CONVERT(varchar(10), DATEADD(yy, -100, CAST(STUFF(STUFF(a.dob,3,0,'/'),6,0,'/') AS DATE)), 101)
ELSE CONVERT(varchar(10), CAST(STUFF(STUFF(a.dob,3,0,'/'),6,0,'/') AS DATE), 101)
END) as dob1
FROM
MyTable a
INNER JOIN
(SELECT
FName, LName, dob,
-- StartDate source format = yyyymm - 200104 , --- result = 2001-04-01 as DATE
MAX(CAST((STUFF(StartDate,5,0,'-') + '-01') AS DATE) ) as StartDate -- original format yyyymm
FROM
MyTable
WHERE
-- mmddyy
CAST(SUBSTRING( dob, 5, 2) as INT) > 31 --yy
AND dob != '999999'
GROUP BY
FName, LName, dob --'mmddyy'
) as t ON
LTRIM(RTRIM(a.FName)) = LTRIM(RTRIM(t.FName)) AND LTRIM(RTRIM(a.LName)) = LTRIM(RTRIM(t.LName))
AND
a.dob = t.dob --'mmddyy'
AND
CAST((STUFF(a.StartDate,5,0,'-') + '-01') AS DATE) = t.StartDate
WHERE ((LTRIM(RTRIM(a.FName)) != '' and
a.FName is not null) or
( LTRIM(RTRIM(a.LName)) != '' and a.LName is not null ) )
and
NOT EXISTS ----------------------------------
-- player does NOT exist in Party DIM alerady
(
select *
from PayrollTable p --- PARTY
where
p.date_of_birth = --t.dob -- varchar(10) 1980-09-07 p.date_of_birth
( -- CASE-2
select
CASE
WHEN CONVERT(DATE, STUFF(STUFF(t.dob,3,0,'/'),6,0,'/')) > CAST(GETDATE() as DATE) --t.dob
THEN CONVERT(varchar(10), DATEADD(yy, -100, CAST(STUFF(STUFF(t.dob,3,0,'/'),6,0,'/') AS DATE)), 101)
ELSE CONVERT(varchar(10), CAST(STUFF(STUFF(t.dob,3,0,'/'),6,0,'/') AS DATE), 101) --t.dob
END
)
and
p.first_name = t.FName
and
p.last_name = t.LName
)
your problem is here.
select *
from PayrollTable p --- PARTY
where
p.date_of_birth = --t.dob -- varchar(10) 1980-09-07 p.date_of_birth
( -- CASE-2
select
CASE
WHEN CONVERT(DATE, STUFF(STUFF(t.dob,3,0,'/'),6,0,'/')) > CAST(GETDATE() as DATE) --t.dob
THEN CONVERT(varchar(10), DATEADD(yy, -100, CAST(STUFF(STUFF(t.dob,3,0,'/'),6,0,'/') AS DATE)), 101)
-- MISSING A WHEN CONDITION HERE
THEN DATEADD(yy, -100, CAST(STUFF(STUFF('090780',3,0,'/'),6,0,'/') AS DATE))
ELSE CONVERT(varchar(10), CAST(STUFF(STUFF(t.dob,3,0,'/'),6,0,'/') AS DATE), 101) --t.dob
END
)

COUNT total by weekly and monthly SQL

I have a table in which I have to count total rows assigned to each USER by daily, weekly and monthly.
Table BooksIssued
BOOKID ISSUEDUSER DATE
1 A 20160708
2 A 20160709
3 A 20160708
4 A 20150102
5 B 20160709
6 C 20160708
7 C 20160708
Now I have to COUNT daily, weekly and monthly books issued to each user
Daily is today (20160709)
Weekly is Sunday through Saturday
Monthly is whole month
The result should be
ISSUEDUSER DAILYBOOKS WEEKLYBOOKS MONTHLYBOOKS
A 1 3 3
B 1 1 1
C 0 2 2
I have done this SQL for daily issued
SELECT ISSUEDUSER, COUNT(BOOKID) AS DAILYBOOKS
FROM BOOKSISSUED
WHERE DATE = CONVERT(VARCHAR(11), SYSDATETIME(), 112)
GROUP BY ISSUEDUSER
Can someone please help me write a combined SQL for all three ?
Thanks
Aiden
you might need to add a WHERE clause to only retrieve current month's records
SELECT ISSUEDUSER,
SUM(CASE WHEN DATE = DATEADD(DAY, DATEDIFF(DAY, 0, SYSDATETIME()), 0))
THEN 1 ELSE 0 END) AS DAILYBOOKS,
SUM(CASE WHEN DATE >= DATEADD(WEEK, DATEDIFF(WEEK, 0, SYSDATETIME()), 0)
AND DATE < DATEADD(WEEK, DATEDIFF(WEEK, 0, SYSDATETIME()) + 1, 0)
THEN 1 ELSE 0 END) AS WEEKLYBOOKS,
COUNT(*) AS MONTHLYBOOKS
FROM BOOKSISSUED
WHERE DATE >= DATEADD(MONTH, DATEDIFF(MONTH, 0, SYSDATETIME()), 0)
AND DATE < DATEADD(MONTH, DATEDIFF(MONTH, 0, SYSDATETIME()) + 1, 0)
GROUP BY ISSUEDUSER
EDIT : for [DATE] column is INT
SELECT ISSUEDUSER,
SUM(CASE WHEN DATE = CONVERT(INT, CONVERT(VARCHAR(8), SYSDATETIME(), 112))
THEN 1 ELSE 0 END) AS DAILYBOOKS,
SUM(CASE WHEN DATE >= CONVERT(INT, CONVERT(VARCHAR(8), DATEADD(WEEK, DATEDIFF(WEEK, 0, SYSDATETIME()), 0), 112))
AND DATE < CONVERT(INT, CONVERT(VARCHAR(8), DATEADD(WEEK, DATEDIFF(WEEK, 0, SYSDATETIME()) + 1, 0), 112))
THEN 1 ELSE 0 END) AS WEEKLYBOOKS,
COUNT(*) AS MONTHLYBOOKS
FROM BOOKSISSUED
WHERE DATE >= CONVERT(INT, CONVERT(VARCHAR(6), SYSDATETIME(), 112) + '01')
AND DATE < CONVERT(INT, CONVERT(VARCHAR(6), DATEADD(MONTH, 1, SYSDATETIME()), 112) + '01')
GROUP BY ISSUEDUSER
You should consider investing in a legitimate Date_Time table.
It makes comparing the official beginning and ending of the weeks MUCH easier and practical. And hey, you might even be able to use indexing!
However, there is another way. AS you shall see, DATEPART returns the ISO Month and Week we are looking for.
So provided our year is right, we now know where our boundaries are and can easily use an IIF(<boolean_expression>, <true_expression>, <false_expression>) statement inside of a COUNT(<column>). COUNT ignores NULLs, so we set TRUE to 1 and FALSE to NULL. :D
-- Note, I changed the column [Date] to [Dates]
DECLARE #Date INT
SET #Date = CAST(CAST(SYSDATETIME() AS VARCHAR(4) ) + '0101' AS INT)
SELECT ISSUEDUSER--DATEPART(YYYY, CAST(Dates AS VARCHAR(10) ) )
, COUNT( IIF(DATEDIFF(MM, CAST(Dates AS VARCHAR(10) ), GETDATE() ) = 0
, 1
, NULL) ) AS MONTHS
, COUNT( IIF(DATEDIFF(WW, CAST(Dates AS VARCHAR(10) ), GETDATE() ) = 0
, 1
, NULL) ) AS Weeks
, COUNT( IIF(DATEDIFF(DD, CAST(Dates AS VARCHAR(10) ), GETDATE() ) = 0
, 1
, NULL) ) AS Days
FROM #BookReport
WHERE DATES >= #Date
GROUP BY ISSUEDUSER
--results
ISSUEDUSER MONTHS Weeks Days
A 3 3 1
B 1 1 1
C 2 2 0
Note that you can expand the allowable date difference by adjusting the boolean statement! No extra coding required.
Also note that your examples actually only have one date that is not of the same Month, Week, or Day (within one day), although in my example I required Days to be of the same day as the query to make it look a bit different.
Cool Observations:
DATE by definition has no formatting and DATEPART can guess from a well-formed Datetime string, so there was no reason to double cast your Date column. However, if your pattern changes, you may need to add a CONVERT.
DATEPART gives you the standard (ISO) Month and Week recognized, which means no Date_Time table required here. :)
DATEDIFF is the magic here, and makes your Boolean statement REALLY easy to work with.
Pretty slick, no?
MSDN's page on DATEPART is worth a quick glance.

Stored Procedure for Calculating hours from 16th of Every Month to 15 of every month

I'm in the process of writing a stored procedure (for SQL Server 2012) that is supposed to calculate the number of hours for our employee from 16-15th of every month.
I have the following database structure
I have written a stored procedure to calculate the hours but I think I can only get the week start date to filter my condition. The stored procedure is returning me the wrong result because the weekly start date is not always the 16th.
CREATE PROCEDURE [dbo].[spGetTotalHoursBetween16to15EveryMonth]
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
DECLARE #SixteenthDate datetime2(7) = DATEADD(DAY, 15, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
DECLARE #currentDate datetime2(7) = getDate()
DECLARE #LastSixteenthDate datetime2(7) = DATEADD(DAY, 15, DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0)), 0))
IF(#currentDate >= #SixteenthDate)
BEGIN
SELECT
(Sum(Day1Hours) + sum(Day2Hours) + Sum(Day3Hours) +
sum(Day4Hours) + Sum(Day5Hours) + sum(Day6Hours) + Sum(Day7Hours)) AS Total
FROM
dbo.TimeSheets
WHERE
WeekStartDate BETWEEN DATEADD(wk, DATEDIFF(wk, 0, #SixteenthDate), -1) AND #currentDate
END
ELSE
BEGIN
SELECT
(Sum(Day1Hours) + sum(Day2Hours) + Sum(Day3Hours) +
sum(Day4Hours) + Sum(Day5Hours) + sum(Day6Hours) + Sum(Day7Hours)) AS Total
FROM
dbo.TimeSheets
WHERE
WeekStartDate BETWEEN DATEADD(wk, DATEDIFF(wk, 0, #LastSixteenthDate), -1) AND #currentDate
END
END TRY
BEGIN CATCH
THROW
END CATCH
END
I'd probably just do it the simple way:
declare #today date = convert(date,current_timestamp)
declare #prev_month_end date = dateadd( day , -day(#today) , #today )
declare #period_start date = dateadd( day , 16 , #prev_month_end ) -- 16th of THIS month
declare #period_end date = dateadd( month , 1 , #period_start ) -- 16th of NEXT month
select #period_start = dateadd(month, -1 , #period_start ) ,
#period_end = dateadd(month, -1 , #period_end )
where day(#today) < 16
select total_hours = coalesce(sum(t.hours),0)
from ( select id = t.id , report_date = dateadd(day,0,t.WeekStartDate) , hours = t.Day1Hours from dbo.TimeSheets t
union all select id = t.id , report_date = dateadd(day,1,t.WeekStartDate) , hours = t.Day2Hours from dbo.TimeSheets t
union all select id = t.id , report_date = dateadd(day,2,t.WeekStartDate) , hours = t.Day3Hours from dbo.TimeSheets t
union all select id = t.id , report_date = dateadd(day,3,t.WeekStartDate) , hours = t.Day4Hours from dbo.TimeSheets t
union all select id = t.id , report_date = dateadd(day,4,t.WeekStartDate) , hours = t.Day5Hours from dbo.TimeSheets t
union all select id = t.id , report_date = dateadd(day,5,t.WeekStartDate) , hours = t.Day6Hours from dbo.TimeSheets t
union all select id = t.id , report_date = dateadd(day,6,t.WeekStartDate) , hours = t.Day7Hours from dbo.TimeSheets t
) t
where t.report_date >= #period_start
and t.report_date < #period_end
Always start with start or an end of a month.
E.g. Here's some logic
Start Date = Start date of previous month + 16
End Date = Start date of current month + 15
Following might help you figure out the dates
-- First Day of the month
select DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)
-- Last Day of previous month
select dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate() ), 0))
More examples are here
Life is easier with a little data normalization. Don't work from the spreadsheet-style table
CREATE VIEW Timesheets_Normalized AS
SELECT
[id]
,[Date] = DATEADD(day,[Date_Offset],[WeekStartDate])
,[Hours]
FROM MyTable a
UNPIVOT([Hours] FOR [Date_Column] IN (Day1Hours,Day2Hours,Day3Hours,Day4Hours,Day5Hours,Day6Hours,Day7Hours)) b
INNER JOIN (VALUES (0,'Day1Hours'),(1,'Day2Hours'),(2,'Day3Hours'),(3,'Day4Hours'),(4,'Day5Hours'),(5,'Day6Hours'),(6,'Day7Hours')) c([Date_Offset],[Date_Column])
ON (b.[Date_Column] = c.[Date_Column])
Then you can get your answers very simply:
SELECT
MIN([Date]) AS [PayrollMonthStart]
,MAX([Date]) AS [PayrollMonthEnd]
,SUM([Hours]) AS [TotalHours]
FROM Timesheets_Normalized
GROUP BY YEAR(DATEADD(day,-15,[Date])),MONTH(DATEADD(day,-15,[Date]))
HAVING CAST(GETDATE() AS date) BETWEEN MIN([Date]) AND MAX([Date])