I am currently try to build report with filter that has Date range (DateTO and DateFrom). The problem is the report need to have ability for date range as optional. THe following is my current SQL. Please advise how i can modify
SELECT
PG.Name AS [Project Group],
PSG.Name AS [Project Sub Group],
P.ReferenceNumber,
P.ReferenceNumber + ' / ' + P.ProjectTitle AS [Project Description],
CASE WHEN W.Removed = 1
THEN 'Yes'
ELSE 'No'
END AS [Removed],
W.Description,
W.CommunicationStartDate,
PR.Name as [Person Responsible],
CASE WHEN W.CommunicationStartDate IS NULL
THEN 'Not Specified'
ELSE CONVERT(NVARCHAR, W.CommunicationStartDate, 103)
END AS [Deadline],
ES.Name AS [Status],
CASE WHEN W.Estimate IS NOT NULL
THEN W.Estimate
ELSE 0
END AS [Estimate]
FROM dbo.ProjectWorkplan W
INNER JOIN dbo.Project P
INNER JOIN dbo.ProjectSubGroup PSG
INNER JOIN dbo.ProjectGroup PG ON PSG.ProjectGroupId = PG.ProjectGroupId
ON P.ProjectSubGroupId = PSG.ProjectSubGroupId
ON W.ProjectId = P.ProjectId
INNER JOIN dbo.PersonResponsible PR ON W.PersonResponsibleId = PR.PersonResponsibleId
INNER JOIN dbo.ElementStatus ES ON W.ElementStatusId = ES.ElementStatusId
WHERE P.DateCompleted IS NULL AND W.Removed = 0
AND W.CommunicationStartDate BETWEEN #DateFrom AND #DateTo
AND ES.NAME in (#ActionRequired, #FollowUp, #OnHold, #UrgentAction, #Waiting,#Complete)
ORDER BY PG.Name, PSG.Name, P.ReferenceNumber, W.Removed, W.CommunicationStartDate
You can check the date parameters for NULL and use them if only both of them are valid:
AND (#DateFrom IS NULL OR #DateTo IS NULL OR W.CommunicationStartDate BETWEEN #DateFrom AND #DateTo)
Related
How do I list the amount of times each account number has occurred if I only want to see the ones that have occurred 3 times or more?
I'm using a window OVER() function to get the number of times the account number is listed.
SELECT a.ACCOUNTNUMBER AS [Account Number]
, CONCAT(n.FIRST, ' ', n.MIDDLE, ' ', n.LAST) AS [Member Name]
, l.id AS [Loan ID]
, COUNT(a.ACCOUNTNUMBER)
OVER(partition by a.ACCOUNTNUMBER) as [Number of
Tracking Record]
, n.EMAIL AS [Email]
, n.HOMEPHONE AS [Phone Number]
FROM dbo.account a
INNER JOIN dbo.LOAN l
ON a.ACCOUNTNUMBER = l.PARENTACCOUNT
INNER JOIN dbo.LOANTRACKING lt
ON l.PARENTACCOUNT = lt.PARENTACCOUNT
AND l.ID = lt.ID
INNER JOIN dbo.NAME n
ON a.ACCOUNTNUMBER = n.PARENTACCOUNT
WHERE lt.type = 46
AND l.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()),
112)
AND lt.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()),
112)
AND a.CLOSEDATE IS NULL
AND lt.EXPIREDATE IS NULL
GROUP BY a.ACCOUNTNUMBER, n.FIRST, n.MIDDLE, n.LAST, l.id, n.email,
n.HOMEPHONE
ORDER BY [Account Number]
Right now my result is giving me the number of times all of the accounts are listed in the "Number of Tracking Record" column. I want to see only the account numbers that have "3" occurrences or above.
My current result:
My Desired Result:
SELECT * -- edit to include only your relevant columnns
FROM
(
SELECT a.ACCOUNTNUMBER AS [Account Number]
, CONCAT(n.FIRST, ' ', n.MIDDLE, ' ', n.LAST) AS [Member Name]
, l.id AS [Loan ID]
, COUNT(a.ACCOUNTNUMBER)
OVER(partition by a.ACCOUNTNUMBER) as [Number of
Tracking Record]
, n.EMAIL AS [Email]
, n.HOMEPHONE AS [Phone Number]
FROM dbo.account a
INNER JOIN dbo.LOAN l
ON a.ACCOUNTNUMBER = l.PARENTACCOUNT
INNER JOIN dbo.LOANTRACKING lt
ON l.PARENTACCOUNT = lt.PARENTACCOUNT
AND l.ID = lt.ID
INNER JOIN dbo.NAME n
ON a.ACCOUNTNUMBER = n.PARENTACCOUNT
WHERE lt.type = 46
AND l.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()),
112)
AND lt.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()),
112)
AND a.CLOSEDATE IS NULL
AND lt.EXPIREDATE IS NULL
GROUP BY a.ACCOUNTNUMBER, n.FIRST, n.MIDDLE, n.LAST, l.id, n.email,
n.HOMEPHONE
) MyQuery
WHERE MyQuery.[Number of Tracking Record] >= 3
ORDER BY [Account Number]
I added an "outer" query around yours, using yours as a subquery, and filtered it for those with just the >=3 condition. And I moved the ORDER BY from your inside query to the outer query, as it's just used for ordering the results and not used in the computation itself.
I'm wondering how to inner join customer name-(CUSTNAM) from table rm001 to this query & have it added to my SSRS Report. Could use help adding this. Thanks
I've tried adding after the "from" saleslineitems as an "and" but it broke the SSRS report.
use n
select distinct a.[SOP Number]
--, [Item Number]
, a.[Customer Number], a.[Created Date from Sales Transaction], a.[Primary Shipto Address Code from Sales Line Item]
, a.[City from Sales Transaction],
,c.city
,case
when b.CITY <> c.city then 'Cities Do Not Match'
when c.city = '' then 'Cities do not Match'
when isnull(c.city,'1') = '1' then 'Cities Do Not Match'
else ''
end as [validate cities]
,b.USERDEF1 as GP_F
, c.f_number as EZ_F
,case
when b.USERDEF1 <> c.f_number then 'Fs do not Match'
when b.USERDEF1 = '' then 'No F in GP'
else ''
end as [validate Fs]
, c.f_expiration
,case
when c.f_expiration <= getdate() then ' F EXPIRED '
when c.f_expiration <= DATEADD(d,15,getDate()) then 'F expiring soon'
--when c.f_expiration >= dateAdd(d,61,getdate()) then 'valid F Expiration'
else ''
end as [valid f date]
--,( select top(1) c.f_number from NBS_BoundBook..contacts where c.f_number = b.userdef1 order by c.uid desc )
--, a.*
from SalesLineItems a
inner join rm00102 b on a.[customer number] = b.CUSTNMBR and a.[Primary Shipto Address Code from Sales Line Item] = b.ADRSCODE
left join NBS_BoundBook..contacts c on Replace(Replace(ltrim(rtrim(b.USERDEF1)),CHAR(10),''),CHAR(13),'') =
( select top(1) Replace(Replace(ltrim(rtrim(c.f_number)),CHAR(10),''),CHAR(13),'') from NBS_BoundBook..contacts
where Replace(Replace(ltrim(rtrim(c.f_number)),CHAR(10),''),CHAR(13),'') = Replace(Replace(ltrim(rtrim(b.USERDEF1)),CHAR(10),''),CHAR(13),'')
and c.city= b.CITY order by c.uid desc )
where [sop type] = 'Order'
and [Created Date from Sales Transaction] >= dateAdd(d,-3, getDate())
and [Item Tracking Option] in ( 'Serial Numbers' )
order by a.[Customer Number]
Something like this should work:
.....
FROM SalesLineItems a
INNER JOIN rm00102 b
ON a.[customer number] = b.CUSTNMBR
AND a.[Primary Shipto Address Code from Sales Line Item] = b.ADRSCODE
INNER JOIN rm001 cust
ON cust.[customer number] = a.[customer number]
LEFT JOIN NBS_BoundBook..contacts c
....
Below is the query which i need to optimize:
DECLARE #Power VARCHAR(10), #Button VARCHAR(10), #Casing VARCHAR(10), #Screen VARCHAR(10)
SELECT #Power = ActivityId FROM t_Activity WHERE ActivityName = 'PhonePowersUp?'
SELECT #Button = ActivityId FROM t_Activity WHERE ActivityName = 'T/S and Buttons functioning OK?'
SELECT #Casing = ActivityId FROM t_Activity WHERE ActivityName = 'Casing - no major defects?'
SELECT #Screen = ActivityId FROM t_Activity WHERE ActivityName = 'LCD works OK?'
SELECT
HQ.HandsetQuoteId [HandsetQuoteId], SS.Name [quote_status], HQ.QuoteDate [Quote Date], INS.DateInspected [DateInspected], PA.IMEI [IMEI_Quoted],
PA1.IMEI [IMEI_Inspected], INS.Grade [Grade], PB.PackageBoxName [PackageBoxName], CC.Name [ContactChannel], PhnBrd.Name [Brand], PM.ModelName [ModelQuoted],
PM1.ModelName [ModelInspected], U.FirstName [FirstName], U.Surname [Surname], U.Username [Username], UW.WarehouseId [WarehouseId], W.Name [Warehouse Name],
HQA.Value [Original Quote Value], HQ.QuoteValue [Quote Value], INS.InspectionValue [InspectionValue], HQ.AgreedValue [Agreed Value], CUS.FirstName [Store Name],
DATEDIFF(DAY, HQ.QuoteDate, GETDATE()) [Quote Age],
[ST_POWER] = CASE WHEN (CHARINDEX(','+ #Power +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Power +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_BUTTONS] = CASE WHEN (CHARINDEX(','+ #Button +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Button +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_CASING] = CASE WHEN (CHARINDEX(','+ #Casing +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Casing +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_Screen] = CASE WHEN (CHARINDEX(','+ #Screen +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Screen +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
st_deduct = PAR.PercentageDeduction, wt_deduct = MAX(APD.PercentageDeduction)
FROM t_Inspection AS INS
INNER JOIN t_HandsetQuote HQ ON HQ.HandsetQuoteId = INS.HandsetQuoteId
INNER JOIN t_QuoteHeader QH ON QH.QuoteHeaderId = HQ.QuoteHeaderId
INNER JOIN t_Customer CUS ON CUS.CustomerId = QH.CustomerId
INNER JOIN t_ContactChannel CC ON CC.ContactChannelId = CUS.ContactChannelId
INNER JOIN t_PackageBoxHandset PBH ON PBH.HandsetQuoteId = HQ.HandsetQuoteId
INNER JOIN t_PackageBox PB ON PB.PackageBoxId = PBH.PackageBoxId
INNER JOIN t_StockStatus SS ON SS.StockStatusId = HQ.StockStatusId
INNER JOIN t_PhoneAudit PA ON PA.PhoneAuditId = HQ.QuotePhoneAuditId
INNER JOIN t_PhoneModel PM ON PM.PhoneModelId = PA.PhoneModelId AND PA.PhoneAuditId = HQ.QuotePhoneAuditId
INNER JOIN t_PhoneBrand PhnBrd ON PM.PhoneBrandId = PhnBrd.PhoneBrandId
INNER JOIN t_PhoneAudit PA1 ON PA1.PhoneAuditId = HQ.InspectionPhoneAuditId
INNER JOIN t_PhoneModel PM1 ON PM1.PhoneModelId = PA1.PhoneModelId AND PA1.PhoneAuditId = HQ.InspectionPhoneAuditId
INNER JOIN t_PhoneBrand PhnBrd1 ON PM1.PhoneBrandId = PhnBrd1.PhoneBrandId
INNER JOIN t_User U ON INS.InspectorId = U.UserId
INNER JOIN t_UserWarehouse UW ON U.UserId = UW.UserId
INNER JOIN t_Warehouse W ON UW.WarehouseId = W.WarehouseId
LEFT JOIN t_HandsetQuoteAdditionalInfo HQA ON HQ.HandsetQuoteId = HQA.HandsetQuoteId AND HQA.KeyName = 'OriginalQuoteValue'
LEFT JOIN t_PhoneAuditRetail PAR ON PAR.HandsetQuoteId = HQ.HandsetQuoteId
LEFT JOIN t_HandsetQuoteActivity HQA1 ON HQA1.HandsetQuoteId = HQ.HandsetQuoteId AND HQA1.ActivityTestOK = 0 AND HQA1.ActivityStartTime = (
CASE
WHEN ((SELECT Count(1) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime <= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId) > 0)
THEN (SELECT Max(ActivityStartTime) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime <= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId GROUP BY HandsetQuoteId, ActivityId)
ELSE
(SELECT Min(ActivityStartTime) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime >= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId GROUP BY HandsetQuoteId, ActivityId)
END)
LEFT JOIN t_Activity_PercentageDeduction APD ON APD.ActivityId = HQA1.ActivityId AND APD.ContactChannelId = CUS.ContactChannelId AND APD.ContactChannelId = CC.ContactChannelId
WHERE Ins.DateInspected > GETDATE()-90
GROUP BY HQ.HandsetQuoteId, SS.Name, QH.CreatedDate, INS.DateInspected, PA.IMEI, PA1.IMEI, INS.Grade, PB.PackageBoxName, CC.Name, PhnBrd.Name, PM.ModelName, PM1.ModelName,
U.FirstName, U.Surname, U.Username, UW.WarehouseId, W.Name, HQA.Value, HQ.QuoteValue, INS.InspectionValue, HQ.AgreedValue, CUS.Firstname, HQ.QuoteDate, PAR.Ok, PAR.Fault,
PAR.PercentageDeduction
And, after properly debugging it, I came to know that when i remove wt_deduct = MAX(APD.PercentageDeduction) from the select list, the query executes with in less than a minute.
But, however i am not able to figure it out, that whats wrong with the column APD.PercentageDeduction, because when i include it in the select list, my query stucks and becomes too slow and takes 15 minutes to run and excluding it from the select list makes the query to run with in 30 seconds.
Additional Information:
Table -> t_Activity_PercentageDeduction contains only 400 records, column PercentageDeduction is of Decimal datatype.
Please let me know if you want some other information too.
If Im not mistaken you are only joining to that table in order to get that MAX value, and by adding this Max value, you are also having to do all the grouping. So there is actually quite a difference in the queries.
I would suggest using a co-related sub-query to get this piece of data.
remove the left join
LEFT JOIN t_Activity_PercentageDeduction APD ON APD.ActivityId = HQA1.ActivityId AND APD.ContactChannelId = CUS.ContactChannelId AND APD.ContactChannelId = CC.ContactChannelId
and set wt_deduct = to the new co-related sub-query
wt_deduct = (select MAX(PercentageDeduction) from t_Activity_PercentageDeduction
where ActivityId = HQA1.ActivityId
AND ContactChannelId = CUS.ContactChannelId
AND ContactChannelId = CC.ContactChannelId)
And you can remove all the grouping that is no longer required too.
following is my Query to generate the Pivoted result:
SELECT '# of Corrective Actions open and overdue' as [Corrective Actions breakdown],
[405],
[2865],
[3142],
[405]+[2865]+[3142] as [Total]
FROM
(Select il.Locationid , ca.CorrectiveActionsid, il.locOrder, ca.isDeleted caDeleted, i.isDeleted iDeleted, i.CompanyId companyid,ca.CADateBy, ca.Status from IncidentLocation il inner join incident i on il.IncidentId = i.IncidentId
inner join CorrectiveActions ca on i.IncidentId = ca.IncidentId
) AS SourceTable
PIVOT
(
COUNT(CorrectiveActionsid)
FOR LocationId IN ([405],[2865],[3142])
) PivotTable
where locOrder = 0 and caDeleted =0 and iDeleted = 0 and companyId = 210
and CADateBy <= '2013-01-01' and [Status] = 'Open'
I was thinking for blank data the count should return o. But I am getting no result at all. Please guide me what wrong I am doing and what should I do to get zero instead of blank for all the counted values.
looks like your query doesn't return any row, you can fix it like this (I've not fixed other parts of query, just want to show you a workaround):
select
A.[Corrective Actions breakdown],
coalesce([405], 0) as [405],
coalesce([2865], 0) as [2865],
coalesce([3142], 0) as [3142],
coalesce([405], 0) + coalesce([2865], 0) + coalesce([3142], 0) as [Total]
from (select '# of Corrective Actions open and overdue' as [Corrective Actions breakdown]) as A
outer apply (
SELECT
[405],
[2865],
[3142]
FROM
(Select il.Locationid , ISNULL(ca.CorrectiveActionsid, 0) AS CorrectiveActionsid, il.locOrder, ca.isDeleted caDeleted, i.isDeleted iDeleted, i.CompanyId companyid,ca.CADateBy, ca.Status from IncidentLocation il inner join incident i on il.IncidentId = i.IncidentId
inner join CorrectiveActions ca on i.IncidentId = ca.IncidentId
) AS SourceTable
PIVOT
(
COUNT(CorrectiveActionsid)
FOR LocationId IN ([405],[2865],[3142])
) PivotTable
where locOrder = 0 and caDeleted =0 and iDeleted = 0 and companyId = 210
and CADateBy <= '2013-01-01' and [Status] = 'Open'
) as p
I would expect the count() to return 0. If it doesn't, you can try using coalesce():
coalesce([405], 0) as [405]
In SQL Server COUNT will ignore NULL values. That being said, use an ISNULL function on the column you are going to aggregate.
SELECT '# of Corrective Actions open and overdue' as [Corrective Actions breakdown],
[405],
[2865],
[3142],
[405]+[2865]+[3142] as [Total]
FROM
(Select il.Locationid , ISNULL(ca.CorrectiveActionsid, 0) AS CorrectiveActionsid, il.locOrder, ca.isDeleted caDeleted, i.isDeleted iDeleted, i.CompanyId companyid,ca.CADateBy, ca.Status from IncidentLocation il inner join incident i on il.IncidentId = i.IncidentId
inner join CorrectiveActions ca on i.IncidentId = ca.IncidentId
) AS SourceTable
PIVOT
(
COUNT(CorrectiveActionsid)
FOR LocationId IN ([405],[2865],[3142])
) PivotTable
where locOrder = 0 and caDeleted =0 and iDeleted = 0 and companyId = 210
and CADateBy <= '2013-01-01' and [Status] = 'Open'
The code below (and numerous codes like it) continues to return blanks.
Basically, if LaborCode = '01 - SC' then it should sort by JobSite, LaborCode, and Schedule (the exact date)
If it's NOT 01 - SC, it should sort by JobSite, LaborCode, and DayNo (the day of the week)
Select Distinct Agreements.AgrmntID, Agreements.Description, Agreements.Status,
JobSites.SiteName, JobSites.Address2, JobSites.City, Customers.CustName,
Customers.CompanyName, LaborCodeTypes.RepairCode As LaborCode, Schedule = Case
LaborCodeTypes.RepairCode
When '01 - SC' Then Left(Convert(varchar,AgreementSchedules.SchedDate,110),
10) Else DateName(dw, AgreementSchedules.SchedDate)
End, Employees1.EmpName As Vendor, Employees.EmpName As [Area Manager],
DatePart(dw, AgreementSchedules.SchedDate) As DayNo
From Agreements Inner Join
Customers On Agreements.CustID = Customers.CustID Inner Join
AgreementSchedules On Agreements.AgrmntID = AgreementSchedules.AgrmntID
Inner Join
JobSites On Agreements.CustSiteID = JobSites.CustSiteID Left Outer Join
LaborCodeTypes On AgreementSchedules.RepairID = LaborCodeTypes.RepairID
Left Outer Join
Employees On AgreementSchedules.FormanEmpID = Employees.EmployeeID Left Join
WorkOrderSchedules On WorkOrderSchedules.ScheduleID =
AgreementSchedules.ScheduleID And AgreementSchedules.ScheduleID =
WorkOrderSchedules.ScheduleID Left Join
WorkOrderScheduleTechs On WorkOrderSchedules.ScheduleID =
WorkOrderScheduleTechs.ScheduleID Left Join
Employees Employees1 On WorkOrderScheduleTechs.EmployeeID =
Employees1.EmployeeID
Where Agreements.Status = 2 And LaborCodeTypes.RepairCode <> 'Vendor Bill' And
Month(AgreementSchedules.SchedDate) = Month(GetDate())
Order By Case
When [LaborCodeTypes.RepairCode] In ('01 - SC') Then JobSites.SiteName +
LaborCodeTypes.RepairCode + Schedule
Else JobSites.SiteName + LaborCodeTypes.RepairCode + DayNo End
Thank you for your help!!
Try this:
ORDER BY JobSites.SiteName,
LaborCodeTypes.RepairCode,
CASE WHEN LaborCodeTypes.RepairCode IN ('01 - SC') THEN Schedule ELSE DayNo END
Okay, in SQL Server:
CREATE PROCEDURE dbo.Agreements_GetList
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT
a.AgrmntID,
a.Description,
a.Status,
js.SiteName,
js.Address2,
js.City,
c.CustName,
c.CompanyName,
LaborCode = lct.RepairCode,
Schedule = CASE lct.RepairCode
WHEN '01 - SC' THEN CONVERT(CHAR(10), aSch.SchedDate, 110)
--------------------^^^ much better than LEFT and not specifying length
ELSE DATENAME(WEEKDAY, aSch.SchedDate) END,
Vendor = e2.EmpName,
[Area Manager] = e1.EmpName,
DayNo = CONVERT(CHAR(1), DATEPART(WEEKDAY, aSch.SchedDate))
--------^^^ this convert is important
FROM dbo.Agreements AS a
INNER JOIN dbo.Customers AS c
ON a.CustID = c.CustID
INNER JOIN dbo.AgreementSchedules AS aSch
ON a.AgrmntID = aSch.AgrmntID
INNER JOIN dbo.JobSites AS js
ON a.CustSiteID = js.CustSiteID
LEFT OUTER JOIN dbo.LaborCodeTypes AS lct
ON aSch.RepairID = lct.RepairID
LEFT OUTER JOIN dbo.Employees AS e1
ON aSch.FormanEmpID = e1.EmployeeID
LEFT OUTER JOIN dbo.WorkOrderSchedules AS w
ON w.ScheduleID = aSch.ScheduleID
LEFT OUTER JOIN dbo.WorkOrderScheduleTechs AS wt
ON w.ScheduleID = wt.ScheduleID
LEFT OUTER JOIN dbo.Employees AS e2
ON wt.EmployeeID = e2.EmployeeID
WHERE
a.Status = 2
AND lct.RepairCode <> 'Vendor Bill'
AND aSch.SchedDate >= DATEADD(MONTH, 0, DATEDIFF(MONTH, 0, GETDATE()))
AND aSch.SchedDate < DATEADD(MONTH, 1, DATEDIFF(MONTH, 0, GETDATE()))
ORDER BY
js.SiteName,
lct.RepairCode,
CASE WHEN lct.RepairCode = '01 - SC'
THEN js.SiteName ELSE DayNo END;
END
GO
Now I have absolutely no knowledge of your application, so you will have to figure out how to call a stored procedure from it instead of embedding SQL.