Dropping rows from the report based on commission date - sql

I need to drop rows (not show) from the report based on commission date completion.
SELECT
proj.ProjectNumber AS [Project],
proj.UserText4 AS [Sales Rep],
bc.Name AS [Customer Name],
proj.Address3 AS [Shiped to],
proj.City,
proj.State,
v_InvDet.InvoiceNumber AS [Invoice],
CASE WHEN CAST(v_InvDet.InvoiceDate as Date) = '01/01/1900'
then NULL else convert(varchar(10), v_InvDet.InvoiceDate, 101)
END AS [Invoice Date],
CASE WHEN CAST(proj.UserDate4 as Date) ='01/01/1900'
then NULL else convert(varchar(10), proj.UserDate4, 101)
END AS [Install Date],
--CASE WHEN CONVERT(DATE, proj.UserDate4) = '1900-01-01'
--THEN NULL
--ELSE CONVERT(CHAR(10), proj.UserDate4, 120)
--+ ' ' + CONVERT(CHAR(8), proj.UserDate4, 108)
--END AS [Install Date],
--case WHEN CONVERT(CHAR(10), proj.UserDate4, 120) > DATEADD( d, -30, GETDATE() )
--THEN proj.UserDate4
--END AS [Install Date],
case WHEN CONVERT(DATE, proj.UserDate4) = '1900-01-01'
THEN NULL
ELSE DATEDIFF(d, CURRENT_TIMESTAMP, proj.UserDate4)*-1
END AS [Open Days],
IIF(proj.UserText9 = 'TRUE', 'YES', 'NO') AS [HVLS Fans],
IIF(proj.UserText18 = 'TRUE', 'YES', 'NO') AS [Restrains],
IIF(proj.UserText23 = 'TRUE', 'YES', 'NO') AS [Docks],
IIF(proj.SitePM = 'TRUE', 'YES', 'NO') AS [Doors],
IIF(proj.ProjectURL = 'TRUE', 'YES', 'NO') AS [Lifts],
proj.UserText2 AS [Commission Equip],
CASE WHEN CAST(proj.Userdate5 as Date) > DATEADD( d, -14, GETDATE() )
then NULL
else convert(varchar(10), proj.Userdate5, 101)
END AS [Commission Date2],
/* Converting 01/01/1900 to NULL so it will show no date on report*/
CASE WHEN CAST(proj.Userdate5 as Date) = '01/01/1900' then NULL else convert(varchar(10), proj.Userdate5, 101)
END AS [Commission Date],
--case WHEN CAST(proj.Userdate5 as Date) = '01/01/1900' > DATEADD( d, -14, GETDATE() )
--THEN proj.UserDate5
--END AS [Commission Date1],
--proj.Userdate5 = DATEADD(d, 14, CURRENT_TIMESTAMP ),
--proj.Userdate5 as [Commission Date],
proj.UserText3 AS [Commission By]
FROM Project proj
LEFT JOIN v_InvoiceDetail As v_InvDet (nolock) ON proj.ProjectNumber = v_InvDet.ProjectNumber
LEFT JOIN Company AS bc (nolock) ON bc.CompanyID = proj.BillingCompanyID
WHERE
proj.Userdate5 >= DATEADD(d, -14, CURRENT_TIMESTAMP)
--proj.Userdate5 >= DATEADD(d, -14, CONVERT(datetime,(convert(varchar(12),proj.Userdate5, 101)))) --getdate())-14
--proj.Userdate4 between '2018-01-01' and CURRENT_TIMESTAMP
--v_InvDet.InvoiceDate between '2018-01-01' and CURRENT_TIMESTAMP
--v_InvDet.InvoiceDate >= DATEDIFF(d, proj.UserDate4, getdate())
--v_InvDet.InvoiceDate >= DATEADD( d, -140, GETDATE() )
ORDER BY proj.UserText4
I am using a "where" close to filter. Is that a way to do it? Thank you

Just wrap your query with another query so that your actual query will be inner query then put your condition.
See This:
select * from (
SELECT
proj.ProjectNumber AS [Project],
proj.UserText4 AS [Sales Rep],
bc.Name AS [Customer Name],
proj.Address3 AS [Shiped to],
proj.City,
proj.State,
v_InvDet.InvoiceNumber AS [Invoice],
CASE WHEN CAST(v_InvDet.InvoiceDate as Date) = '01/01/1900'
then NULL else convert(varchar(10), v_InvDet.InvoiceDate, 101)
END AS [Invoice Date],
CASE WHEN CAST(proj.UserDate4 as Date) ='01/01/1900'
then NULL else convert(varchar(10), proj.UserDate4, 101)
END AS [Install Date],
--CASE WHEN CONVERT(DATE, proj.UserDate4) = '1900-01-01'
--THEN NULL
--ELSE CONVERT(CHAR(10), proj.UserDate4, 120)
--+ ' ' + CONVERT(CHAR(8), proj.UserDate4, 108)
--END AS [Install Date],
--case WHEN CONVERT(CHAR(10), proj.UserDate4, 120) > DATEADD( d, -30, GETDATE() )
--THEN proj.UserDate4
--END AS [Install Date],
case WHEN CONVERT(DATE, proj.UserDate4) = '1900-01-01'
THEN NULL
ELSE DATEDIFF(d, CURRENT_TIMESTAMP, proj.UserDate4)*-1
END AS [Open Days],
IIF(proj.UserText9 = 'TRUE', 'YES', 'NO') AS [HVLS Fans],
IIF(proj.UserText18 = 'TRUE', 'YES', 'NO') AS [Restrains],
IIF(proj.UserText23 = 'TRUE', 'YES', 'NO') AS [Docks],
IIF(proj.SitePM = 'TRUE', 'YES', 'NO') AS [Doors],
IIF(proj.ProjectURL = 'TRUE', 'YES', 'NO') AS [Lifts],
proj.UserText2 AS [Commission Equip],
CASE WHEN CAST(proj.Userdate5 as Date) > DATEADD( d, -14, GETDATE() )
then NULL
else convert(varchar(10), proj.Userdate5, 101)
END AS [Commission Date2],
/* Converting 01/01/1900 to NULL so it will show no date on report*/
CASE WHEN CAST(proj.Userdate5 as Date) = '01/01/1900' then NULL else convert(varchar(10), proj.Userdate5, 101)
END AS [Commission Date],
--case WHEN CAST(proj.Userdate5 as Date) = '01/01/1900' > DATEADD( d, -14, GETDATE() )
--THEN proj.UserDate5
--END AS [Commission Date1],
--proj.Userdate5 = DATEADD(d, 14, CURRENT_TIMESTAMP ),
--proj.Userdate5 as [Commission Date],
proj.UserText3 AS [Commission By]
FROM Project proj
LEFT JOIN v_InvoiceDetail As v_InvDet (nolock) ON proj.ProjectNumber = v_InvDet.ProjectNumber
LEFT JOIN Company AS bc (nolock) ON bc.CompanyID = proj.BillingCompanyID
WHERE
proj.Userdate5 >= DATEADD(d, -14, CURRENT_TIMESTAMP)
--proj.Userdate5 >= DATEADD(d, -14, CONVERT(datetime,(convert(varchar(12),proj.Userdate5, 101)))) --getdate())-14
--proj.Userdate4 between '2018-01-01' and CURRENT_TIMESTAMP
--v_InvDet.InvoiceDate between '2018-01-01' and CURRENT_TIMESTAMP
--v_InvDet.InvoiceDate >= DATEDIFF(d, proj.UserDate4, getdate())
--v_InvDet.InvoiceDate >= DATEADD( d, -140, GETDATE() )
)
where [Commission Date] not in ( ....)
ORDER BY proj.UserText4

Related

Create view with variable declaration defined by a case expression, generating a dynamic date table based on getdate() reference

I have static date table and a working query that I use to add references fields for comparison between financial periods, I would like to save as a view however the variable declaration is not permitted.
Query is shown below, the specific issues is with declaring "#this_qtr_month" and calculating "Is QTD". The variable determines [Num of Month in QTR] for today.
declare #this_qtr_month as int = case when month(getdate()) in (1,4,7,10) then 1
when month(getdate()) in (2,5,8,11) then 2
when month(getdate()) in (3,6,9,12) then 3
end
select *
,DATEDIFF(day,[Date],getdate()) as 'Days Aged'
,DATEDIFF(ww,[Date],getdate()) as 'Weeks Aged'
,DATEDIFF(qq,[Date],getdate()) as 'QTRs Aged'
,DATEDIFF(yy,[Date],getdate()) as 'Years Aged'
,case when DATEPART(dd,[Date]) <= DATEPART(dd,getdate()) then 'Y' else 'N' end as 'Is MTD'
,case when #this_qtr_month > [Num of Month in QTR] then 'Y'
when #this_qtr_month = [Num of Month in QTR] and DATEPART(dd,[Date]) <= DATEPART(dd,getdate()) then 'Y'
else 'N'
end as 'Is QTD'
,case when getdate() >= DATEFROMPARTS(year(getdate()), [Month Num], day(date_modified_LeapYear)) then 'Y' else 'N' end as 'Is YTD'
from Date_Table_Static
You could write that without a variable:
SELECT *,
DATEDIFF(DAY, [Date], GETDATE()) AS 'Days Aged',
DATEDIFF(ww, [Date], GETDATE()) AS 'Weeks Aged',
DATEDIFF(qq, [Date], GETDATE()) AS 'QTRs Aged',
DATEDIFF(yy, [Date], GETDATE()) AS 'Years Aged',
CASE
WHEN DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is MTD',
CASE
WHEN (CASE
WHEN MONTH(GETDATE()) IN ( 1, 4, 7, 10 ) THEN
1
WHEN MONTH(GETDATE()) IN ( 2, 5, 8, 11 ) THEN
2
WHEN MONTH(GETDATE()) IN ( 3, 6, 9, 12 ) THEN
3
END
) > [Num of Month in QTR] THEN
'Y'
WHEN (CASE
WHEN MONTH(GETDATE()) IN ( 1, 4, 7, 10 ) THEN
1
WHEN MONTH(GETDATE()) IN ( 2, 5, 8, 11 ) THEN
2
WHEN MONTH(GETDATE()) IN ( 3, 6, 9, 12 ) THEN
3
END
) = [Num of Month in QTR]
AND DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is QTD',
CASE
WHEN GETDATE() >= DATEFROMPARTS(YEAR(GETDATE()), [Month Num], DAY(date_modified_LeapYear)) THEN
'Y'
ELSE
'N'
END AS 'Is YTD'
FROM Date_Table_Static;
Or, since all you need with this view is a SELECT, you could write that as a Stored Procedure or TVF (Table Valued Function).
EDIT: I didn't read your expression before, it doesn't need to be that complex:
SELECT *,
DATEDIFF(DAY, [Date], GETDATE()) AS 'Days Aged',
DATEDIFF(ww, [Date], GETDATE()) AS 'Weeks Aged',
DATEDIFF(qq, [Date], GETDATE()) AS 'QTRs Aged',
DATEDIFF(yy, [Date], GETDATE()) AS 'Years Aged',
CASE
WHEN DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is MTD',
CASE
WHEN (Month(Getdate())-1)%3+1 > [Num of Month in QTR] THEN
'Y'
WHEN (Month(Getdate())-1)%3+1 = [Num of Month in QTR]
AND DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is QTD',
CASE
WHEN GETDATE() >= DATEFROMPARTS(YEAR(GETDATE()), [Month Num], DAY(date_modified_LeapYear)) THEN
'Y'
ELSE
'N'
END AS 'Is YTD'
FROM Date_Table_Static;

SQL - AVG Output is incorrect

In below query, I am calculating the lead time between two different dates and eventually trying to get the average of that lead time but the output is incorrect.
SELECT
Round(AVG(CAST(
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, INVOUTDATE, 105)) = 'Sunday' THEN 0 ELSE 0 END) end end AS FLOAT)),4) AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
To troubleshoot the above query I extract the data by using the same query below and when I manually calculate the lead time and average it was correct.
Don't know where is the issue? can someone please tell me whether anything wrong with my query.
Please click on the link to refer sample data Link
SELECT DISTINCT DOCKETNO,
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, INVOUTDATE, 105)) = 'Sunday' THEN 0 ELSE 0 END) end end AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
ok, now I understand..
I think you have to group by orders before to calculate avg
;with
S AS (
select DOCKETNO, ORDERDATE, INVOUTDATE, COUNT(*) n
from DSORDERSTATUS where ORDERTYPE <> 'Exchange Order'
group by DOCKETNO, ORDERDATE, INVOUTDATE
),
D as (
select [DOCKETNO], [ORDERDATE], [INVOUTDATE],
DATEDIFF(dd, CONVERT(date, [ORDERDATE], 105), CONVERT(date, [INVOUTDATE], 105)) dd,
DATEDIFF(wk, CONVERT(date, [ORDERDATE], 105), CONVERT(date, [INVOUTDATE], 105)) wk,
CASE WHEN DATEPART(dw, CONVERT(datetime, ORDERDATE, 105)) = 7 THEN 1 ELSE 0 END IsSundayOrd,
CASE WHEN DATEPART(dw, CONVERT(datetime, INVOUTDATE, 105)) = 7 THEN 1 ELSE 0 END IsSundayInv
from S
)
select avg(cast(dd - case when dd>1 then (wk + IsSundayOrd + IsSundayInv) else 0 end as float)) leadtime
from D
where CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL
I will try to convert your dates to DATE instesad of DATETIME I think you are filtering too much rows because '20170831' is '2017-08-31 00:00:00' and you are loosing all ORDERDATE between '00:00:00' and '23:59:59' (for '2017-08-31')
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL
With the help of MtwStark i was able to resolve this.
I have modified his query,
Thanks buddy
;with
S AS (
SELECT DISTINCT DOCKETNO,
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)end end AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170808'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
),
D AS (
SELECT DOCKETNO, LEADTIME FROM S
)
SELECT AVG(CAST(LEADTIME AS FLOAT)) FROM D

Data Table with Current Week and Those Dates One Year Ago

I'm trying to create one sql table with the current week's data (always changing) as well as those dates data from the previous year. I have multiple tables that I have to join but am not sure how to create it all into one table. Here is what I have so far:
------- CURRENT YEAR -------
DECLARE
#CURRENTDATE DATE,
#BEGINDATE DATE
SET #CURRENTDATE = CONVERT(DATE,GETDATE()) ---// TODAY'S DATE //---
SET #BEGINDATE = DATEADD(DAY, -7, GETDATE()) ---// A WEEK BEFORE TODAY'S DATE //---
SELECT SALES.*, RECRUITS.Recruits
FROM
(
SELECT
CONVERT(VARCHAR(10), A.[ORDER DATE], 101) AS 'DAY'
, 'Sales Revenue Current Year' = FORMAT(SUM(A.[GRAND TOTAL]) ,'C', 'EN-US')
, 'Comm. Sales Volume Current Year' = FORMAT(sum(a. [QUALIFYING VOLUME]), 'C', 'EN-US')
FROM TABLE1 a
WHERE CONVERT(VARCHAR(10), A.[ORDER DATE], 101) >= #BEGINDATE AND CONVERT(VARCHAR(10), A.[ORDER DATE], 101) < #CURRENTDATE
GROUP BY CONVERT(VARCHAR(10), A.[ORDER DATE], 101)
) SALES,
(
SELECT
CONVERT(VARCHAR(10),a.[start date],101) AS 'DAY'
,count(b.[id number]) as Recruits
from TABLE2 a
left join
TABLE3 b
on a.enroller = b. [id number]
WHERE CONVERT(VARCHAR(10), A.[START DATE], 101) >= #BEGINDATE AND CONVERT(VARCHAR(10), A.[START DATE], 101) < #CURRENTDATE
group by a.[start date]
) RECRUITS
WHERE SALES.DAY = RECRUITS.DAY
I have the same script for the previous year. It is the same except I set the dates to -366 and -373 days. Any help would be great!
You can use multiple dates with an "OR", like below, but a better solution would be to use a date dimensional table, a list of every daily date with things like "WeekOfYear", "WeekOfMonth", "QuarterOfYear", "IsHoliday", etc. Then you can join your date against that table and query "where t1.WeekOfYear = t2.WeekOfYear".
DECLARE
#EndDate DATE = GETDATE() ---// TODAY'S DATE //---
, #StartDate DATE = DATEADD(DAY, -7, GETDATE()) ---// A WEEK BEFORE TODAY'S DATE //---
, #LYStartDate DATE = DATEADD(YEAR, -1, GETDATE()) ---// A YEAR BEFORE TODAY'S DATE //---
, #LYEndDate DATE = DATEADD(DAY, -7, DATEADD(YEAR, -1, GETDATE())) ---// A YEAR AND A WEEK BEFORE TODAY'S DATE //---
SELECT SALES.*, RECRUITS.Recruits
FROM
(
SELECT
'DAY' = CONVERT(VARCHAR(10), A.[ORDER DATE], 101)
, 'Sales Revenue Current Year' = FORMAT(SUM(A.[GRAND TOTAL]) ,'C', 'EN-US')
, 'Comm. Sales Volume Current Year' = FORMAT(sum(a. [QUALIFYING VOLUME]), 'C', 'EN-US')
FROM TABLE1 a
WHERE (
(CAST(A.[ORDER DATE] AS DATE) >= #StartDate AND CAST(A.[ORDER DATE] AS DATE) <= #EndDate)
OR
(CAST(A.[ORDER DATE] AS DATE) >= #LYStartDate AND CAST(A.[ORDER DATE] AS DATE) <= #lyEndDate)
)
GROUP BY CAST(A.[ORDER DATE] AS DATE)
) SALES,
(
SELECT
'DAY' = CAST(a.[start date] AS DATE)
, Recruits = COUNT(b.[id number])
FROM TABLE2 a
LEFT JOIN TABLE3 b
ON a.enroller = b. [id number]
WHERE (
(CAST(A.[START DATE] AS DATE) >= #StartDate AND CAST(A.[ORDER DATE] AS DATE) <= #EndDate)
OR
(CAST(A.[START DATE] AS DATE) >= #lyStartDate AND CAST(A.[ORDER DATE] AS DATE) <= #LYEndDate)
GROUP BY CAST(a.[start date] AS DATE)
) RECRUITS
WHERE SALES.DAY = RECRUITS.DAY

SQL Only Include Working Hours in AVG Calculation

I'v had a look through the forum but couldn't find anything specific enough for my scenario so here goes.
I have the following query which calculates the average time for a group of entries across multiple tables in a defined date period. The 3 types (IR, SR, CR) all are linked to a table (WorkItems). The Query I have for the average time is below. (the parameters are used in reporting services and a date picker)
Select
WIAvgAssign = AVG(
Case When WI.id Like 'IR%' Then DATEDIFF(hour,wi.CreatedDate,IR.FirstAssignedDate)
When WI.Id Like 'SR%' Then DATEDIFF(hour,wi.CreatedDate,SR.FirstAssignedDate)
When WI.Id Like 'SR%' Then DATEDIFF(hour,wi.CreatedDate,CR.FirstAssignedDate)
END),
IRAvgAssign = AVG(DATEDIFF(hour,wi.CreatedDate,IR.FirstAssignedDate)),
SRAvgAssign = AVG(DATEDIFF(hour,wi.CreatedDate,SR.FirstAssignedDate)),
CRAvgAssign = AVG(DATEDIFF(hour,wi.CreatedDate,CR.FirstAssignedDate))
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR on WI.EntityDimKey=CR.EntityDimKey
Where (IR.ResolvedDate >= #StartDate AND IR.ResolvedDate < #EndDate) OR
(SR.CompletedDate >= #StartDate AND SR.CompletedDate < #EndDate) OR
(CR.ActualEndDate >=#StartDate AND CR.ActualEndDate < #EndDate)
I have a table which contains each day of the week and the hours of operation for that particular day (the date is when the entry was created, it's just the time I'm interested in), the values for the weekend are blank.
Day Start Time End Time
Monday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Tuesday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Wednesday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Thursday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Friday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Saturday NULL NULL
Sunday NULL NULL
The average results in hours that I get currently are not specific to the hours of operation so I would like to be able to strip out when the office is closed and provide a more accurate average.
Thanks
Edit - I've come up with this, it's a bit inefficient as I've specified the number of non-working hours manually in the query and added in a calculation for weekends. Looking at the individual records I think it's correct. I've taken out the CR calculation for the time being
Declare #StartDate datetime
Declare #EndDate datetime
Set #StartDate = '2015/01/01'
Set #EndDate = '2015/12/31'
Select
AVG(
CASE WHEN CAST(wi.createddate as date) =
CAST(
CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END
as date)
THEN DATEDIFF(HOUR,wi.CreatedDate,
CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END)
ELSE (DATEDIFF(hour,wi.CreatedDate,DATEADD(hour,-15*DATEDIFF(day,wi.CreatedDate,CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END),CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END)))-48*DATEDIFF(wk,wi.CreatedDate,CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END)
END)
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR on WI.EntityDimKey=CR.EntityDimKey
WHERE (wi.Id like 'IR%' or WI.ID like 'SR%') AND
((IR.ResolvedDate >=#StartDate AND IR.ResolvedDate < #EndDate) OR
(Sr.CompletedDate >=#StartDate AND SR.CompletedDate < #EndDate))
After many more hours of tweaking I've come up with the following which I'm 90% sure is right. If there is any way of optimising the query that would be helpful.
Declare #StartDate datetime
Declare #EndDate datetime
Set #StartDate = '2016/01/01'
Set #EndDate = '2016/12/31'
SELECT
WIAvgAssign = AVG(
Case
When id Like 'IR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedIRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedIRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)
When id Like 'SR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedSRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedSRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)
When id Like 'CR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedCRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedCRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)
END),
IRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedIRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedIRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)),
SRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedSRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedSRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)),
CRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedCRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedCRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END))
FROM (
Select WI.id,
CASE
WHEN wi.CreatedDate < DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
ELSE wi.CreatedDate
END NormalizedCreatedDate,
CASE
WHEN IR.FirstAssignedDate !=NULL THEN CASE
WHEN IR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE IR.FirstAssignedDate END
ELSE CASE WHEN IR.ResolvedDate > DATEADD(HOUR, 17, CAST(CAST(IR.ResolvedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(IR.ResolvedDate AS DATE) AS DATETIME))
ELSE IR.ResolvedDate END
END NormalizedIRAssignedDate,
CASE
WHEN SR.FirstAssignedDate !=NULL THEN CASE
WHEN SR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE SR.FirstAssignedDate END
ELSE CASE WHEN SR.CompletedDate > DATEADD(HOUR, 17, CAST(CAST(SR.CompletedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(SR.CompletedDate AS DATE) AS DATETIME))
ELSE SR.CompletedDate END
END NormalizedSRAssignedDate,
CASE
WHEN CR.FirstAssignedDate !=NULL THEN CASE
WHEN CR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE CR.FirstAssignedDate END
ELSE CASE WHEN CR.ActualEndDate > DATEADD(HOUR, 17, CAST(CAST(CR.ActualEndDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(CR.ActualEndDate AS DATE) AS DATETIME))
ELSE CR.ActualEndDate END
END NormalizedCRAssignedDate
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR
on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR
on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR
on WI.EntityDimKey=CR.EntityDimKey
Where (
(IR.ResolvedDate >= #StartDate AND IR.ResolvedDate < #EndDate)
OR (SR.CompletedDate >= #StartDate AND SR.CompletedDate < #EndDate)
OR (CR.ActualEndDate >= #StartDate AND CR.ActualEndDate < #EndDate)
)
) dataset
Edit - obviously we weren't excluding the time after 5pm (it's between 8 and 6 in my example as that's what my customer wanted) so I added in a calculation to remove 14 hours for every day (apart from weekends) the item is open which has given me what I believe to be the exact figures
This has been an intriguing question for me. I assumed a few things in my approach to this one:
CreatedDate always happens before FirstAssignedDate
SET DATEFIRST 7 (changes weekday numbers if different)
That is is okay to filter out CreatedDate and FirstAssignedDate if they are on a weekend
Here's my approach and I'm sure that it's wildly inefficient, but it was my first idea:
SELECT
WIAvgAssign = AVG(
Case
When id Like 'IR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)
When id Like 'SR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)
When id Like 'SR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate)
END
),
IRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)),
SRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)),
CRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate))
FROM (
Select WI.id,
CASE
WHEN wi.CreatedDate < DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
ELSE wi.CreatedDate
END NormalizedCreatedDate,
CASE
WHEN IR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE IR.FirstAssignedDate
END NormalizedIRAssignedDate,
CASE
WHEN SR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE SR.FirstAssignedDate
END NormalizedSRAssignedDate,
CASE
WHEN CR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE CR.FirstAssignedDate
END NormalizedCRAssignedDate
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR
on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR
on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR
on WI.EntityDimKey=CR.EntityDimKey
--AVOID SATURDAYS and SUNDAYS in result set
--Also assumes SET DATEFIRST 7
Where DATEPART(WEEKDAY,wi.CreatedDate) NOT IN (1,7)
AND DATEPART(WEEKDAY,IR.FirstAssignedDate) NOT IN (1,7)
AND DATEPART(WEEKDAY,SR.FirstAssignedDate) NOT IN (1,7)
AND DATEPART(WEEKDAY,CR.FirstAssignedDate) NOT IN (1,7)
AND(
(IR.ResolvedDate >= #StartDate AND IR.ResolvedDate < #EndDate)
OR (SR.CompletedDate >= #StartDate AND SR.CompletedDate < #EndDate)
OR (CR.ActualEndDate >= #StartDate AND CR.ActualEndDate < #EndDate)
)
) dataset
So I basically just check if the CreatedDate < 0900 of the same day and set the time to 0900 if that is the case, and then I check if FirstAssignedDate > 1700 of the same day and set the time to 1700 if that is the case. I also filtered out all of the CreatedDates and FirstAssignedDates if they were on a weekend.
EDIT:
I updated the my original post. I changed the date checks to use DATEADD rather than building a string and trying to convert the string to a DATETIME

How do I pull date criteria from multiple columns from ONE table?

I've been working with SQL for a little time so fairly new but have been catching on very quick. I have this very intense query I need to create for a report - I have this in excel and use IF statements and works perfectly.
Here's what I have and need:
I have one table with multiple columns containing dates.
One 'Raving Fan Name' could have more than one date. These are the possibilities / example:
RavingFan ID 1 = FU Date + Testimonial Date + Bonus Date
RavingFan ID 2 = Referral Date + Signed Date
RavingFan ID 3 = Testimonial Date
I need to pull data from each column containing a date filter (of a rolling 6 months) I've read multiple select select statements. This is what I have but it tells me I need a EXISTS - hopefully someone can help!!
SELECT
(SELECT
rf.Raving_Fan_ID,
rf.Raving_Fan_Name,
cr.Contact_Role_Name,
emp.Emp_Name,
rf.FU_Detail,
rf.FU_Date,
rf.FU_Point,
rf.Bonus_Date,
rf.Bonus_Point
FROM Raving_Fans AS rf
LEFT JOIN Employees AS emp ON rf.Emp_ID = emp.Emp_ID
LEFT JOIN Contact_Role AS cr ON rf.Contact_Role_ID = cr.Contact_Role_ID
WHERE rf.FU_Date BETWEEN DATEADD(day,-181,getdate()) AND DATEADD(day,0,getdate())
)
(SELECT
rf.Raving_Fan_ID,
rf.Raving_Fan_Name,
cr.Contact_Role_Name,
emp.Emp_Name,
rf.Test_Detail,
rf.Test_Date,
rf.Test_Point,
rf.Bonus_Date,
rf.Bonus_Point
FROM Raving_Fans AS rf
LEFT JOIN Employees AS emp ON rf.Emp_ID = emp.Emp_ID
LEFT JOIN Contact_Role AS cr ON rf.Contact_Role_ID = cr.Contact_Role_ID
WHERE rf.Test_Date BETWEEN DATEADD(day,-181,getdate()) AND DATEADD(day,0,getdate())
)
(SELECT
rf.Raving_Fan_ID,
rf.Raving_Fan_Name,
cr.Contact_Role_Name,
emp.Emp_Name,
rf.Ref_Detail,
rf.Ref_Date,
rf.Ref_Point,
rf.Signed_Date,
rf.Signed_Point,
rf.Bonus_Date,
rf.Bonus_Point
FROM Raving_Fans AS rf
LEFT JOIN Employees AS emp ON rf.Emp_ID = emp.Emp_ID
LEFT JOIN Contact_Role AS cr ON rf.Contact_Role_ID = cr.Contact_Role_ID
WHERE rf.Ref_Date BETWEEN DATEADD(day,-181,getdate()) AND DATEADD(day,0,getdate())
)
I'm having a hard time wrapping my head around this. Is there an easier way to do this? Any help is appreciated.
This is how it is done, If you want to pull certain criteria from multiple columns.
SET NOCOUNT ON;
SELECT
rf.Raving_Fan_ID,
rf.Raving_Fan_Name AS "Raving Fan",
cr.Contact_Role_Name AS "Contact Type",
emp.Emp_Name AS "TCS Employee",
rf.FU_Detail AS "Follow Ups",
CASE WHEN rf.FU_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.FU_Date ELSE NULL END AS "FU Date",
CASE WHEN rf.FU_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.FU_Point ELSE NULL END AS "FU Point",
rf.Test_Detail AS "Testimonials",
CASE WHEN rf.Test_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Test_Date ELSE NULL END AS "Test Date",
CASE WHEN rf.Test_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Test_Point ELSE NULL END AS "Test Point",
rf.Ref_Detail AS "Referrals",
CASE WHEN rf.Ref_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Ref_Date ELSE NULL END AS "Ref Date",
CASE WHEN rf.Ref_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Ref_Point ELSE NULL END AS "Ref Point",
CASE WHEN rf.Signed_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Signed_Date ELSE NULL END AS "Signed Date",
CASE WHEN rf.Signed_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Signed_Point ELSE NULL END AS "Signed Point",
CASE WHEN rf.Bonus_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Bonus_Date ELSE NULL END AS "Bonus Date",
CASE WHEN rf.Bonus_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Bonus_Point ELSE NULL END AS "Bonus Point",
(CASE WHEN rf.Ref_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Ref_Point ELSE 0 END +
CASE WHEN rf.Signed_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Signed_Point ELSE 0 END +
CASE WHEN rf.FU_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.FU_Point ELSE 0 END +
CASE WHEN rf.Test_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Test_Point ELSE 0 END +
CASE WHEN rf.Bonus_Date BETWEEN CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()) THEN rf.Bonus_Point ELSE 0 END) AS "Total Points"
FROM [dbo].[Raving_Fans] AS rf
LEFT JOIN Employees AS emp ON rf.Emp_ID = emp.Emp_ID
LEFT JOIN Contact_Role AS cr ON rf.Contact_Role_ID = cr.Contact_Role_ID
WHERE (rf.FU_Date between CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()))
OR (rf.Test_Date between CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()))
OR (rf.Ref_Date between CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()))
OR (rf.Signed_Date between CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()))
OR (rf.Bonus_Date between CONVERT(date,DATEADD(month, -6, GETDATE())) and CONVERT(date, GETDATE()))
AND(emp.Emp_Name LIKE '%' +#Emp_Name+ '%' OR #Emp_Name IS NULL)
ORDER BY emp.Emp_Name ASC;