Adding weekdays to select statement - sql

I have a select statement that pulls and consolidates data from multiple tables. I need to add additional logic to calculate the number of weekdays between the createdDt and CallEndDate (but if the callEndDate is null use the current date).
We are using SQL Server 2016 and am at a loss on how to incorporate this additional calculated logic with my select statement below. Any suggestions?
SELECT c.ID, c.CreatedDt, c.LastUpdatedDt, c.CALLSTARTDT, c.CALLENDDT, c.DUEDT,
c.TYPE, c.DESCRIPTION, c.COMMENT, c.CONTRACT, c.DISCLOSUREPTAN, c.DISCLOSURENPI, c.DISCLOSURETIN,
c.DISCLOSUREIVR, c.CALLERFIRSTNAME, c.CALLERLASTNAME, c.CALLERPHONE, c.CALLEREMAIL, c.STATUS,
c.STATUSQUALIFIER, c.RATING, u1.Name as LastUpdatedByName, u2.Name as CreatedByName,
u3.Name as OwnedByName, p.PTAN, p.NPI,p.NAME, con.LOB
FROM Case c
LEFT JOIN ossys_User u1 ON c.LastUpdatedBy = u1.Id
LEFT JOIN ossys_User u2 ON c.CreatedBy = u2.ID
LEFT JOIN ossys_User u3 ON c.OwnedBy = u3.Id
INNER JOIN PROVIDER p ON c.TargetId = p.Id
INNER JOIN CONTRACTS con ON p.Contract = con.Contract
WHERE
c.LastUpdatedDt BETWEEN '2019-01-01' AND '2019-07-01'
Order By c.CreatedDt ASC

Calculations can be included in your select statement as such:
SELECT c.ID, c.CreatedDt, c.LastUpdatedDt, c.CALLSTARTDT, c.CALLENDDT, c.DUEDT,
c.TYPE, c.DESCRIPTION, c.COMMENT, c.CONTRACT, c.DISCLOSUREPTAN,
c.DISCLOSURENPI,c.DISCLOSURETIN,c.DISCLOSUREIVR, c.CALLERFIRSTNAME, c.CALLERLASTNAME,
c.CALLERPHONE, c.CALLEREMAIL, c.STATUS, c.STATUSQUALIFIER, c.RATING,
u1.Name as LastUpdatedByName, u2.Name as CreatedByName,
u3.Name as OwnedByName,
p.PTAN, p.NPI,p.NAME,
con.LOB,
((DATEDIFF(dd, c.CreateDt, ISNULL(c.CALLENDDT,#GETDATE)) + 1)
-(DATEDIFF(wk, c.CreateDt, ISNULL(c.CALLENDDT,#GETDATE)) * 2)
-(CASE WHEN DATENAME(dw, c.CreateDt) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, ISNULL(c.CALLENDDT, #GETDATE)) = 'Saturday' THEN 1 ELSE 0 END))
As diff
FROM Case c
LEFT JOIN ossys_User u1 ON c.LastUpdatedBy = u1.Id
LEFT JOIN ossys_User u2 ON c.CreatedBy = u2.ID
LEFT JOIN ossys_User u3 ON c.OwnedBy = u3.Id
INNER JOIN PROVIDER p ON c.TargetId = p.Id
INNER JOIN CONTRACTS con ON p.Contract = con.Contract
WHERE
c.LastUpdatedDt BETWEEN '2019-01-01' AND '2019-07-01'
Order By c.CreatedDt ASC
Although I would more likely go with the solution defined by the link posted by #openshac and put that into a function before calling as such.
CREATE FUNCTION [dbo].fn_CountWeekDays
(
#fromdate Datetime,
#todate Datetime
)
RETURNS TABLE AS RETURN
(
SELECT
(DATEDIFF(dd, #fromdate, #todate) + 1)
-(DATEDIFF(wk, #fromdate, #todate) * 2)
-(CASE WHEN DATENAME(dw, #fromdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, #todate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays
)
GO
SELECT c.ID, c.CreatedDt, c.LastUpdatedDt, c.CALLSTARTDT, c.CALLENDDT, c.DUEDT,
c.TYPE, c.DESCRIPTION, c.COMMENT, c.CONTRACT, c.DISCLOSUREPTAN,
c.DISCLOSURENPI,c.DISCLOSURETIN,c.DISCLOSUREIVR, c.CALLERFIRSTNAME, c.CALLERLASTNAME,
c.CALLERPHONE, c.CALLEREMAIL, c.STATUS, c.STATUSQUALIFIER, c.RATING,
u1.Name as LastUpdatedByName, u2.Name as CreatedByName,
u3.Name as OwnedByName,
p.PTAN, p.NPI,p.NAME,
con.LOB,
CountWeekDays(c.CreateDt, ISNULL(c.CALLENDDT,#GETDATE))
As diff
FROM Case c
LEFT JOIN ossys_User u1 ON c.LastUpdatedBy = u1.Id
LEFT JOIN ossys_User u2 ON c.CreatedBy = u2.ID
LEFT JOIN ossys_User u3 ON c.OwnedBy = u3.Id
INNER JOIN PROVIDER p ON c.TargetId = p.Id
INNER JOIN CONTRACTS con ON p.Contract = con.Contract
WHERE
c.LastUpdatedDt BETWEEN '2019-01-01' AND '2019-07-01'
Order By c.CreatedDt ASC

Related

How to make a cell blank in a row from a query result?

I have a query as below:
SELECT
cc.chain_desc as chain_desc
,cc.chain_id as chain_id
,COUNT(distinct t.trans_id) as TranCount
FROM TRANSACTION AS t
LEFT OUTER JOIN location AS l
ON t.location_id = l.location_id
LEFT OUTER JOIN trans_line AS tl
ON t.trans_id = tl.trans_id
LEFT OUTER JOIN contract as c
ON t.contract_id = c.contract_id
LEFT OUTER JOIN chain_desc as cc
ON l.chain_id = cc.chain_id
WHERE
t.loc_country = 'U'
AND c.issuer_id IN (156966,166203)
AND t.trans_date >= '2016-10-01 00:00'
and t.trans_date < '2016-10-31 00:00'
AND tl.cat NOT IN ('DEF','DEFD','DEFC')
GROUP BY cc.chain_desc, cc.chain_id
UNION
SELECT
'TOTAL'
,0
,COUNT(distinct t.trans_id)
FROM TRANSACTION AS t
LEFT OUTER JOIN location AS l
ON t.location_id = l.location_id
LEFT OUTER JOIN trans_line AS tl
ON t.trans_id = tl.trans_id
LEFT OUTER JOIN contract as c
ON t.contract_id = c.contract_id
LEFT OUTER JOIN chain_desc as cc
ON l.chain_id = cc.chain_id
WHERE
t.loc_country = 'U'
AND c.issuer_id IN (156966,166203)
AND t.trans_date >= '2016-10-01 00:00'
and t.trans_date < '2016-10-31 00:00'
AND tl.cat NOT IN ('DEF','DEFD','DEFC')
The above query when executed reurns the below result:
I need the result to be displayed as below:
The column "Chain_Id" is of "integer" type, how can I make that blank?.
you can simply select null
.....
UNION
SELECT
'TOTAL'
, NULL::INTEGER
,COUNT(distinct t.trans_id)
FROM TRANSACTION AS t
LEFT OUTER JOIN location AS l
ON t.location_id = l.location_id
LEFT OUTER JOIN trans_line AS tl
ON t.trans_id = tl.trans_id
LEFT OUTER JOIN contract as c
ON t.contract_id = c.contract_id
LEFT OUTER JOIN chain_desc as cc
ON l.chain_id = cc.chain_id
WHERE
t.loc_country = 'U'
AND c.issuer_id IN (156966,166203)
AND t.trans_date >= '2016-10-01 00:00'
and t.trans_date < '2016-10-31 00:00'
AND tl.cat NOT IN ('DEF','DEFD','DEFC')
because null is not a type you could try add above the first query
DEFINE test INT;
LET test = NULL;
......
SELECT
'TOTAL'
, test
,COUNT(distinct t.trans_id)
.....
Or like suggusted by #Jonathan Leffler use NULL::INTEGER or CAST(NULL AS INTEGER)
In Informix you can use NULL in the projection list, but the column must have a type. Since in Informix NULL does not have a type, you need to use a CAST.
SELECT NULL::INTEGER AS id FROM systables WHERE tabid = 1;
SELECT CAST(NULL AS INTEGER) AS id FROM systables WHERE tabid = 1;
You can check the answers to this other question (Informix: Select null problem).
You can check the IBM Knowledge Center (NULL Keyword).
One way is to convert to NULL:
(case when cc.chain_id <> 0 then cc.chain_id end) as chain_id
Another is to convert everything to a string:
(case when cc.chain_id <> 0 then cast(cc.chain_id as varchar(255)) else '' end) as chain_id

How to join 4 tables based on PK column?

In my stored procedure I have four select queries. These queries have a single column JobDescriptionCode common in them. I want to join these tables on that column.
This is my stored procedure :
SELECT a.JobDescriptionCode, ISNULL(a.ApprovedCount,0) - ISNULL(b.ApprovedCount,0) AS StructureChange
FROM
(select rh.JobDescriptionCode, SUM(ApprovedCount) as ApprovedCount from RequisitionHistory rh
left join OGJobDescription jd on rh.JobDescriptionCode = jd.JobDescriptionCode
where Convert(varchar(8),rh.CreationDate,1) between #PreviousMonthStartDate and #PreviousMonthEndDate
GROUP by rh.JobDescriptionCode) a
INNER JOIN
(select rh.JobDescriptionCode, SUM(ApprovedCount) as ApprovedCount from RequisitionHistory rh
left join OGJobDescription jd on rh.JobDescriptionCode = jd.JobDescriptionCode
where Convert(varchar(8),rh.CreationDate,1) between #startDate and #endDate
GROUP by rh.JobDescriptionCode) b
on a.JobDescriptionCode = b.JobDescriptionCode
select r.JobDescriptionCode, count(*) as NewJoining from CandidateHistory ch
left join Requisition r on ch.RequisitionCode = r.RequisitionCode
where ch.StatusCode = 6005 and Convert(varchar(8),ch.CreationDate,1) between #startDate and #endDate
GROUP BY r.JobDescriptionCode
select r.JobDescriptionCode, count(*) as Separation from CandidateHistory ch
left join Requisition r on ch.RequisitionCode = r.RequisitionCode
where ch.StatusCode = 10005 and Convert(varchar(8),ch.CreationDate,1) between #startDate and #endDate
GROUP BY r.JobDescriptionCode
SELECT r.JobDescriptionCode, d.DepartmentName,jd.JobDescriptionName, SUM(r.ApprovedCount) as ApprovedCount, SUM(r.FilledCount) as FilledCount,
SUM(r.UnfilledCount) as UnfilledCount from Requisition r
left join OGJobDescription jd on r.JobDescriptionCode = jd.JobDescriptionCode
left join OGDepartment d on r.DepartmentCode = d.DepartmentCode
where Convert(varchar(8),r.RequisitionDate,1) between #startDate and #endDate
GROUP BY jd.JobDescriptionName, d.DepartmentName, r.JobDescriptionCode
Now dates are passed as a parameter to the SP and are based on 1 month. Now some queries return 2 rows, some 10 and so on. I just want to match the PK JobDescriptionCode and on that, join the tables.
Is it possible, if so how?
You can treat every separate query as a subquery and join them together like this:
SELECT q1.JobDescriptionCode, StructureChange, NewJoining, Separation, DepartmentName, JobDescriptionName, ApprovedCOUNT, FilledCOUNT, UnfilledCOUNT
FROM (
SELECT
a.JobDescriptionCode,
ISNULL(a.ApprovedCOUNT,0) - ISNULL(b.ApprovedCOUNT,0) AS StructureChange
FROM (
SELECT rh.JobDescriptionCode, SUM(ApprovedCOUNT) AS ApprovedCOUNT
FROM RequisitionHistory rh
LEFT JOIN OGJobDescription jd ON rh.JobDescriptionCode = jd.JobDescriptionCode
WHERE CONVERT(VARCHAR(8),rh.CreationDate,1) BETWEEN #PreviousMonthStartDate AND #PreviousMonthEndDate
GROUP BY rh.JobDescriptionCode
) a
INNER JOIN (
SELECT rh.JobDescriptionCode, SUM(ApprovedCOUNT) AS ApprovedCOUNT
FROM RequisitionHistory rh
LEFT JOIN OGJobDescription jd ON rh.JobDescriptionCode = jd.JobDescriptionCode
WHERE CONVERT(VARCHAR(8),rh.CreationDate,1) BETWEEN #startDate AND #endDate
GROUP BY rh.JobDescriptionCode
) b ON a.JobDescriptionCode = b.JobDescriptionCode
) q1
INNER JOIN (
SELECT r.JobDescriptionCode, COUNT(*) AS NewJoining
FROM CANDidateHistory ch
LEFT JOIN Requisition r ON ch.RequisitionCode = r.RequisitionCode
WHERE ch.StatusCode = 6005 AND CONVERT(VARCHAR(8),ch.CreationDate,1) BETWEEN #startDate AND #endDate
GROUP BY r.JobDescriptionCode
) q2 ON q1.JobDescriptionCode = q2.JobDescriptionCode
INNER JOIN (
SELECT r.JobDescriptionCode, COUNT(*) AS Separation
FROM CANDidateHistory ch
LEFT JOIN Requisition r ON ch.RequisitionCode = r.RequisitionCode
WHERE ch.StatusCode = 10005 AND CONVERT(VARCHAR(8),ch.CreationDate,1) BETWEEN #startDate AND #endDate
GROUP BY r.JobDescriptionCode
) q3 ON q1.JobDescriptionCode = q3.JobDescriptionCode
INNER JOIN (
SELECT
r.JobDescriptionCode,
d.DepartmentName,
jd.JobDescriptionName,
SUM(r.ApprovedCOUNT) AS ApprovedCOUNT,
SUM(r.FilledCOUNT) AS FilledCOUNT,
SUM(r.UnfilledCOUNT) AS UnfilledCOUNT
FROM Requisition r
LEFT JOIN OGJobDescription jd ON r.JobDescriptionCode = jd.JobDescriptionCode
LEFT JOIN OGDepartment d ON r.DepartmentCode = d.DepartmentCode
WHERE CONVERT(VARCHAR(8),r.RequisitionDate,1) BETWEEN #startDate AND #endDate
GROUP BY jd.JobDescriptionName, d.DepartmentName, r.JobDescriptionCode
) q4 ON q1.JobDescriptionCode = q4.JobDescriptionCode
After looking a little at your queries I think it could be simplified a bit, will look a little more.
Edit: I think this query should be equivalent, but without test data it's a bit hard to confirm. If it produces the correct output it might perform better:
SELECT
q1.JobDescriptionCode,
q1.StructureChange,
q2.NewJoining,
q2.Separation,
q3.DepartmentName,
q3.JobDescriptionName,
q3.ApprovedCount,
q3.FilledCount,
q3.UnFilledCount
FROM (
SELECT rh.JobDescriptionCode,
SUM(CASE
WHEN CONVERT(VARCHAR(8),rh.CreationDate,1) BETWEEN #startDate AND #endDate THEN -ApprovedCount
WHEN CONVERT(VARCHAR(8),rh.CreationDate,1) BETWEEN #PreviousMonthStartDate AND #PreviousMonthEndDate THEN ApprovedCount
END) AS StructureChange
FROM RequisitionHistory rh
LEFT JOIN OGJobDescription jd ON rh.JobDescriptionCode = jd.JobDescriptionCode
GROUP BY rh.JobDescriptionCode
) q1
INNER JOIN (
SELECT
r.JobDescriptionCode,
SUM(CASE WHEN ch.StatusCode = 6005 THEN 1 ELSE 0 END) AS NewJoining,
SUM(CASE WHEN ch.StatusCode = 10005 THEN 1 ELSE 0 END) AS Separation
FROM CandidateHistory ch
LEFT JOIN Requisition r ON ch.RequisitionCode = r.RequisitionCode
WHERE CONVERT(VARCHAR(8),ch.CreationDate,1) BETWEEN #startDate AND #endDate
GROUP BY r.JobDescriptionCode
) q2 ON q1.JobDescriptionCode = q2.JobDescriptionCode
INNER JOIN (
SELECT
r.JobDescriptionCode,
d.DepartmentName,
jd.JobDescriptionName,
SUM(r.ApprovedCount) AS ApprovedCount,
SUM(r.FilledCount) AS FilledCount,
SUM(r.UnFilledCount) AS UnFilledCount
FROM Requisition r
LEFT JOIN OGJobDescription jd ON r.JobDescriptionCode = jd.JobDescriptionCode
LEFT JOIN OGDepartment d ON r.DepartmentCode = d.DepartmentCode
WHERE CONVERT(VARCHAR(8),r.RequisitionDate,1) BETWEEN #startDate AND #endDate
GROUP BY jd.JobDescriptionName, d.DepartmentName, r.JobDescriptionCode
) q3 ON q1.JobDescriptionCode = q3.JobDescriptionCode
Try putting all your queries into WITH like this:
WITH table_alias1 AS (
SELECT ...
),
table_alias2 AS (
SELECT .. ),
table_alias3 AS (
SELECT .. ),
table_alias4 AS (
SELECT .. )
SELECT * FROM
table_alias1 t1 INNER JOIN
table_alias2 t2 ON t1.JobDescriptionCode = t2.JobDescriptionCode INNER JOIN
table_alias2 t3 ON t1.JobDescriptionCode = t3.JobDescriptionCode INNER JOIN
table_alias2 t4 ON t1.JobDescriptionCode = t4.JobDescriptionCode;
Your queries are massive, so I did not put them here for readability reasons.

Order By Case multiple fields

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.

SQL Sum is counting more than once

I am having difficulty with this. This query worked fine in calculating the sums until I put the first inner join in. In the table tbl_companies there are multiple entries per company, for example the table could look like this:
priority company externalip
1 bla 9.9.9.9
1 bla 3.3.3.3
1 company2 3.56.6.6
In the below query the sum (that calculates As TotalWithoutNew and TotalAllId is doubling when there is more than one entry for the company, and tripling if there is three etc. What I want it to do is simply bring back the priority from the table tbl_companies
SELECT b.company,
b.priority,
i.concom,
Coalesce (SUM(CASE
WHEN c.category_id = '30' THEN 0
ELSE t.logmins
END), 0) AS totalwithoutnew,
Coalesce (SUM(t.logmins), 0) AS totalallid
FROM helpdesk3.dbo.inquiry AS i
INNER JOIN [Check].[dbo].[tbl_companies] AS b
ON i.concom = b.company COLLATE sql_latin1_general_cp1_ci_as
INNER JOIN timelog AS t
ON t.inquiry_id = i.inquiry_id
INNER JOIN prod AS p
ON i.prod_id = p.prod_id
INNER JOIN category AS c
ON p.category_id = c.category_id
WHERE ( Datepart(yyyy, escdate) = 2011 )
GROUP BY i.concom,
b.company,
b.priority
ORDER BY totalwithoutnew DESC,
b.priority DESC
You should split the query to avoid multiple results from tbl_companies.
select distinct b.company,
b.priority,
x.concom,
x.totalwithoutnew,
x.totalallid
FROM (
SELECT i.concom,
Coalesce (SUM(CASE
WHEN c.category_id = '30' THEN 0
ELSE t.logmins
END), 0) AS totalwithoutnew,
Coalesce (SUM(t.logmins), 0) AS totalallid
FROM helpdesk3.dbo.inquiry AS i
INNER JOIN timelog AS t
ON t.inquiry_id = i.inquiry_id
INNER JOIN prod AS p
ON i.prod_id = p.prod_id
INNER JOIN category AS c
ON p.category_id = c.category_id
WHERE ( Datepart(yyyy, escdate) = 2011 )
GROUP BY i.concom
) x
INNER JOIN [Check].[dbo].[tbl_companies] AS b
ON x.concom = b.company COLLATE sql_latin1_general_cp1_ci_as
ORDER BY x.totalwithoutnew DESC,
b.priority DESC
Your join from the INQUIRY table to the tbl_companies table is going to generate a set of three rows (when there are three companies) so the next join to the TIMELOG table is also going to have three values for each TIMELOG.LOGMINS column - therefore it follows that the COALESCE (SUM(CASE WHEN C.CATEGORY_ID = '30' THEN 0 ELSE t.LOGMINS END), 0) AS TotalWithoutNew calculation will be tripled.
select
...
FROM helpdesk3.dbo.INQUIRY AS i
inner join [Check].[dbo].[tbl_companies] As B ON i.CONCOM = B.company COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID
...
If you want a single company to appear in the select and not multiply up the sum remove the join to tbl_companies from the where clause and the group by clause. Something along these lines should work (although without knowing the exact structure of the data I can't be certain):
select
(select company from [tbl_companies] where company = i.concom) as company,
(select priority from [tbl_companies] where company = i.concom) as priority,
...
FROM helpdesk3.dbo.INQUIRY AS i
INNER JOIN TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID
...
There are a couple of ways of doing this. Assuming that priority, company and externalip uniquely identify tbl_companies records, I suggest:
SELECT b.company,
b.priority,
i.concom,
Coalesce (SUM(CASE
WHEN c.category_id = '30' THEN 0
ELSE t.logmins
END), 0) / COUNT(DISTINCT b.externalip) AS totalwithoutnew,
Coalesce (SUM(t.logmins), 0) / COUNT(DISTINCT b.externalip) AS totalallid
FROM helpdesk3.dbo.inquiry AS i
INNER JOIN [Check].[dbo].[tbl_companies] AS b
ON i.concom = b.company COLLATE sql_latin1_general_cp1_ci_as
INNER JOIN timelog AS t
ON t.inquiry_id = i.inquiry_id
INNER JOIN prod AS p
ON i.prod_id = p.prod_id
INNER JOIN category AS c
ON p.category_id = c.category_id
WHERE ( Datepart(yyyy, escdate) = 2011 )
GROUP BY i.concom,
b.company,
b.priority
ORDER BY totalwithoutnew DESC,
b.priority DESC

Follow on - Multiple Sums in SQL Query

Thanks to Quassnoi before who gave me the answer I was looking for - this led to a seperate problem though. Current code:
SELECT i.CONCOM, COALESCE (SUM(t.LOGMINS), 0) AS TotalWithoutNew
FROM INQUIRY AS i INNER JOIN
TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID INNER JOIN
PROD AS P ON i.PROD_ID = P.PROD_ID INNER JOIN
CATEGORY AS C ON P.CATEGORY_ID = C.CATEGORY_ID
WHERE (DATEPART(month, i.ESCDATE) = DATEPART(month, GETDATE()) - 1) AND (DATEPART(year, i.ESCDATE) = DATEPART(year, DATEADD(m, - 1, GETDATE()))) AND
(C.CATEGORY_ID <> '30')
GROUP BY i.CONCOM
ORDER BY TotalWithoutNew DESC
This brings back exactly what I want (C.CATEGORY_ID <> 30) is not included in the initial column marked as TotalWithoutNew. I also need the value WITH it in as well though. Is there any way to have another column called TotalWithNew that includes all CATEGORY_IDs? I am certain learning a lot of new query language today!
SELECT i.CONCOM,
COALESCE (SUM(CASE WHEN C.CATEGORY_ID = '30' THEN 0 ELSE t.LOGMINS END), 0) AS TotalAllID,
COALESCE (SUM(t.LOGMINS), 0) AS TotalWithoutNew
FROM INQUIRY AS i INNER JOIN
TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID INNER JOIN
PROD AS P ON i.PROD_ID = P.PROD_ID INNER JOIN
CATEGORY AS C ON P.CATEGORY_ID = C.CATEGORY_ID
WHERE (DATEPART(month, i.ESCDATE) = DATEPART(month, GETDATE()) - 1) AND (DATEPART(year, i.ESCDATE) = DATEPART(year, DATEADD(m, - 1, GETDATE())))
GROUP BY i.CONCOM
ORDER BY TotalWithoutNew DESC
Note: I haven't tried but I hope you get the idea of using CASE WHEN ....
SELECT i.CONCOM
, COALESCE(SUM(CASE WHEN C.CATEGORY_ID <> 30 THEN t.LOGMINS END), 0)
AS TotalWithoutNew
, COALESCE(SUM(t.LOGMINS), 0) AS TotalWithNew
FROM INQUIRY AS i INNER JOIN
TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID INNER JOIN
PROD AS P ON i.PROD_ID = P.PROD_ID INNER JOIN
CATEGORY AS C ON P.CATEGORY_ID = C.CATEGORY_ID
WHERE (DATEPART(month, i.ESCDATE) = DATEPART(month, GETDATE()) - 1)
AND (DATEPART(year, i.ESCDATE) = DATEPART(year, DATEADD(m, - 1, GETDATE())))
GROUP BY i.CONCOM
ORDER BY TotalWithoutNew DESC