I have designed the following sql query to get the percentage of
100 - ((reportedDate – Submission Date) / TotalNumOfVisits) * 100
Is there any way to simplify it? Like combine the two queries into one?
SELECT
q1.VisitMonth,q1.TotalVisit, ISNULL(q2.diff,0) AS DIFF
,100 - ISNULL( (CAST((q2.diff * 1.0 / q1.TotalVisit ) * 100 AS FLOAT)),0) PERC
FROM
(
SELECT DATENAME(MONTH,v.VisitDate) as VisitMonth, count(v.VisitID) as TotalVisit
FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID
WHERE a.ClientID IN (33,46)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'
group by DATENAME(MONTH,v.VisitDate)
) q1
LEFT OUTER JOIN
(
SELECT DATENAME(MONTH,v.VisitDate) as MonthName,COUNT(*) as diff
FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID
WHERE a.ClientID IN (33,46)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'
AND DATEDIFF(DAY,v.ReportDate,v.SubmissionDate) > 2
group by DATENAME(MONTH,v.VisitDate)
) q2
ON q1.VisitMonth = q2.MonthName
Result:
Try this :-
Select
VisitMonth,isnull(diff,0) as DIFF,
100 - ISNULL( (CAST((diff * 1.0 / Nullif(TotalVisit,0) ) * 100 AS FLOAT)),0) PERC
from
(
SELECT
VisitMonth = Datename(month,visitDate) ,
Diff = Sum(case when DATEDIFF(DAY,v.ReportDate,v.SubmissionDate) > 2 then 1
else 0 end) ,
TotalVisit = Count(v.VisitID)
FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID
WHERE a.ClientID IN (33,46)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'
group by DATENAME(MONTH,v.VisitDate)
)a
Related
I have 2 working queries that are joined by subselects using WITH in DB2.
They each work separately but I can't seem to find the best way to properly combine or union them.
The first query:
with c as(
select
employee,
sum(salesPrice) as priorSpecifics
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2018-01-01' and '2018-01-31'
and g.details = 'CategoryOne'
group by employee
), d as(
select
employee,
sum(salesPrice) as priorTotals
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2018-01-01' and '2018-01-31'
group by employee
)
Select ifnull(c.employee,d.employee) as employee
,c.priorSpecifics
,d.priorTotals
,cast(Round((DEC(c.priorSpecifics,12,2)/DEC(d.priorTotals,12,2)) * 100,2) as decimal(12,2)) as priorPercent
from c full join d ON (c.employee = d.employee);
Returns 4 columns
and the 2nd query
with c as(
select
employee,
sum(salesPrice) as currentSpecifics
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2019-01-01' and '2019-01-31'
and g.details = 'CategoryOne'
group by employee
), d as(
select
employee,
sum(salesPrice) as currentTotals
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2019-01-01' and '2019-01-31'
group by employee
)
Select ifnull(c.employee,d.employee) as employee
,c.currentSpecifics
,d.currentTotals
,cast(Round((DEC(c.currentSpecifics,12,2)/DEC(d.currentTotals,12,2)) * 100,2) as decimal(12,2)) as currentPercent
from c full join d ON (c.employee = d.employee);
Returns 4 as well. The field employee is the only thing that is shared between all.
How can I combine this into one query to get one employee column and then all of my sum/percent columns following?
I think you can do everything you want with conditional aggregation:
select employee,
sum(case when d.newDate between '2018-01-01' and '2018-01-31' and g.details = 'CategoryOne' then salesPrice end) as priorSpecifics,
sum(case when d.newDate between '2019-01-01' and '2019-01-31' and g.details = 'CategoryOne' then salesPrice end) as currentSpecifics,
sum(case when d.newDate between '2018-01-01' and '2018-01-31' then salesPrice end) as priorTotals,
sum(case when d.newDate between '2019-01-01' and '2019-01-31' then salesPrice end) as currentTotals
from schema1.orders g inner join
dateSchema.dates d
on g.dateField = d.dateField
group by employee;
I'll let you fill in with the additional calculations.
If all the above queries are working then you already have everything you need.
You must combine from the 1st group, the first 2 to make the prior query, then
from the 2nd group to make the cur query
and finally join the prior query to the cur query:
with
c as(
select
employee,
sum(salesPrice) as priorSpecifics
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2018-01-01' and '2018-01-31'
and g.details = 'CategoryOne'
group by employee
),
d as(
select
employee,
sum(salesPrice) as priorTotals
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2018-01-01' and '2018-01-31'
group by employee
),
prior as (
Select ifnull(c.employee,d.employee) as employee
,c.priorSpecifics
,d.priorTotals
,cast(Round((DEC(c.priorSpecifics,12,2)/DEC(d.priorTotals,12,2)) * 100,2) as decimal(12,2)) as priorPercent
from c full join d ON (c.employee = d.employee)
),
e as(
select
employee,
sum(salesPrice) as currentSpecifics
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2019-01-01' and '2019-01-31'
and g.details = 'CategoryOne'
group by employee
),
f as(
select
employee,
sum(salesPrice) as currentTotals
from schema1.orders g
inner join dateSchema.dates d
on g.dateField = d.dateField
where d.newDate between '2019-01-01' and '2019-01-31'
group by employee
),
cur as (
Select ifnull(e.employee,f.employee) as employee
,e.currentSpecifics
,f.currentTotals
,cast(Round((DEC(e.currentSpecifics,12,2)/DEC(f.currentTotals,12,2)) * 100,2) as decimal(12,2)) as currentPercent
from e full join f ON (e.employee = f.employee)
)
Select ifnull(p.employee, c.employee) as employee
,p.priorSpecifics
,p.priorTotals
,p.priorPercent
,c.currentSpecifics
,c.currentTotals
,c.currentPercent
from prior p full join cur c ON (c.employee = c.employee);
I have been working on a query to gather some information and I'm getting a little bit stuck.
In my query, I have a CASE statement to look at the Unit of Measure, and do a calculation dependent on whether or not the unit is one or the other.
My problem is that when I am looking at a particular record, it is showing as 2 records when I would like it to just show as 1, but add up the figures from both.
Unfortunately the reason why the 2 records show is because I am forced to have a group by on the unit, and as they are different they split over 2 lines.
My query is this:
Select
C.CaseID,
DATEPART(Year,C.ResolvedDate) 'Year',
DATENAME(Month,C.ResolvedDate) 'Month',
CASE
WHEN
I.ItemGroupID IN ('FGBCTFLR','FGBCTFLD','FGBCTLIS','FGBCTSAM','FGBCTSEC') THEN 'ManufacturedCeramics'
WHEN
I.ItemGroupID = 'FGBCTGLS' THEN 'ManufacturedGlass'
WHEN
I.ItemGroupID IN ('FGFACTAG','FGFACTFLD','FGFACTFLR','FGFACTLIS','FGTOOLS') THEN 'Factored'
End as 'Category',
COALESCE(CASE WHEN D.UnitID = 'BOX' THEN
SUM(D.QtyAffected * I.BCT_Product_Qty / (1 / NULLIF((convert(decimal(18,3),I.BCT_Product_Width) / 1000 * convert(decimal(18,3),I.BCT_Product_Height) / 1000),0)))
ELSE
SUM(D.QtyAffected / (1 / NULLIF((convert(decimal(18,3),I.BCT_Product_Width) / 1000 * convert(decimal(18,3),I.BCT_Product_Height) / 1000),0)))
End,0) as 'M2 Affected',
C.CostReplacementTile + C.CostRedelivery + C.CostCredit + C.CostRefixing + C.CostVoucher 'Cost'
From BCTComplaintRegister C
Left Join BCTComplaintProductRegister D
On D.CaseID = C.CaseID
Left Join InventTable I
On I.ItemID = D.ItemID
Left Join BCTTileSize T
On T.TileSizeID = I.BCTTileSize
Where
DATEDIFF(M,C.ResolvedDate,GETDATE()) <= 12
And C.QAOutcome IN (1,2,5)
And C.Status = '4'
AND C.CaseID = 'CE20300'
Group By
DATEPART(Year,C.ResolvedDate),
DATENAME(Month,C.ResolvedDate),
I.ItemGroupID,
C.CaseID,
C.CostReplacementTile,
c.costredelivery,
c.costcredit,
c.costrefixing,
c.costvoucher,
d.unitid
Order By
C.CaseId
The results are the following:
CaseID: CE20300, CE20300 <br>
Year: 2016, 2016<br>
Month: April, April<br>
Category: ManCer, ManCer<br>
M2 Affected: 23.56, 0.81
Cost: 2292, 2292
(sorry not sure how to do a table on here).
I need this to show as one line but with the M2 as a total value for both, the cost should stay the same.
How can I achieve this?
Sorry if anything is unclear.
Can you turn the COALESCE expression into a subquery that is grouped on unitid?
Select
C.CaseID,
DATEPART(Year,C.ResolvedDate) 'Year',
DATENAME(Month,C.ResolvedDate) 'Month',
CASE
WHEN
I.ItemGroupID IN ('FGBCTFLR','FGBCTFLD','FGBCTLIS','FGBCTSAM','FGBCTSEC') THEN 'ManufacturedCeramics'
WHEN
I.ItemGroupID = 'FGBCTGLS' THEN 'ManufacturedGlass'
WHEN
I.ItemGroupID IN ('FGFACTAG','FGFACTFLD','FGFACTFLR','FGFACTLIS','FGTOOLS') THEN 'Factored'
End as 'Category',
sum(D.M2Affected) as 'M2 Affected',
C.CostReplacementTile + C.CostRedelivery + C.CostCredit + C.CostRefixing + C.CostVoucher 'Cost'
From BCTComplaintRegister C
Left Join (select
COALESCE(CaseID, CASE WHEN D.UnitID = 'BOX' THEN
SUM(D.QtyAffected * I.BCT_Product_Qty / (1 / NULLIF((convert(decimal(18,3),I.BCT_Product_Width) / 1000 * convert(decimal(18,3),I.BCT_Product_Height) / 1000),0)))
ELSE
SUM(D.QtyAffected / (1 / NULLIF((convert(decimal(18,3),I.BCT_Product_Width) / 1000 * convert(decimal(18,3),I.BCT_Product_Height) / 1000),0)))
End,0) as M2Affected
from BCTComplaintProductRegister group by unitid) D
On D.CaseID = C.CaseID
Left Join InventTable I
On I.ItemID = D.ItemID
Left Join BCTTileSize T
On T.TileSizeID = I.BCTTileSize
Where
DATEDIFF(M,C.ResolvedDate,GETDATE()) <= 12
And C.QAOutcome IN (1,2,5)
And C.Status = '4'
AND C.CaseID = 'CE20300'
Group By
DATEPART(Year,C.ResolvedDate),
DATENAME(Month,C.ResolvedDate),
I.ItemGroupID,
C.CaseID,
C.CostReplacementTile,
c.costredelivery,
c.costcredit,
c.costrefixing,
c.costvoucher
Order By
C.CaseId;
Try to split up the query to calculate M2 Affected separately.
SELECT *
INTO #temp1
FROM
(
Select
C.CaseID,
DATEPART(Year,C.ResolvedDate) 'Year',
DATENAME(Month,C.ResolvedDate) 'Month',
CASE
WHEN
I.ItemGroupID IN ('FGBCTFLR','FGBCTFLD','FGBCTLIS','FGBCTSAM','FGBCTSEC') THEN 'ManufacturedCeramics'
WHEN
I.ItemGroupID = 'FGBCTGLS' THEN 'ManufacturedGlass'
WHEN
I.ItemGroupID IN ('FGFACTAG','FGFACTFLD','FGFACTFLR','FGFACTLIS','FGTOOLS') THEN 'Factored'
End as 'Category',
C.CostReplacementTile + C.CostRedelivery + C.CostCredit + C.CostRefixing + C.CostVoucher 'Cost'
From BCTComplaintRegister C
Left Join BCTComplaintProductRegister D
On D.CaseID = C.CaseID
Left Join InventTable I
On I.ItemID = D.ItemID
Left Join BCTTileSize T
On T.TileSizeID = I.BCTTileSize
Where
DATEDIFF(M,C.ResolvedDate,GETDATE()) <= 12
And C.QAOutcome IN (1,2,5)
And C.Status = '4'
AND C.CaseID = 'CE20300'
Group By
DATEPART(Year,C.ResolvedDate),
DATENAME(Month,C.ResolvedDate),
I.ItemGroupID,
C.CaseID,
C.CostReplacementTile,
c.costredelivery,
c.costcredit,
c.costrefixing,
c.costvoucher,
d.unitid
) P
SELECT
COALESCE(CASE WHEN D.UnitID = 'BOX' THEN
SUM(D.QtyAffected * I.BCT_Product_Qty / (1 / NULLIF((convert(decimal(18,3),I.BCT_Product_Width) / 1000 * convert(decimal(18,3),I.BCT_Product_Height) / 1000),0)))
ELSE
SUM(D.QtyAffected / (1 / NULLIF((convert(decimal(18,3),I.BCT_Product_Width) / 1000 * convert(decimal(18,3),I.BCT_Product_Height) / 1000),0)))
End,0) as 'M2 Affected'
INTO #temp2
FROM BCTComplaintProductRegister D
Left Join InventTable I
On I.ItemID = D.ItemID
Group By
D.unitid
SELECT
T1.CaseID,
Year,
Month,
Category,
Cost,
SUM(T2.[M2 Affected]) AS [M2 Affected]
FROM #temp1 T1
INNER JOIN #temp2 T2
ON T1.CaseID = T2.CaseID
Group By
T1.CaseID,
Year,
Month,
Category,
Cost
Order By
C.CaseId
The last 2 select queries can be merged if it works.
I have following query, which works fine:
SELECT c.id, c.customer_name, b.batch_prefix, b.BatchCount, b.InvoiceCount, e.time_of_delivery, e.time_of_delivery_mail, e.time_of_delivery_clock
FROM koll_customers c
INNER JOIN (
SELECT batch_prefix, COUNT(*) AS BatchCount,
SUM (batch_counter) AS InvoiceCount
FROM koll_batchlogs
WHERE
exists_db = 0
and is_checked = 1
and batch_counter > 0
and trunc(created_date) > trunc(sysdate-7)
GROUP BY batch_prefix) b
ON b.batch_prefix=c.customer_prefix
INNER JOIN (
SELECT id, time_of_delivery, time_of_delivery_mail, time_of_delivery_clock
FROM koll_customer_export) e
ON e.id = c.id
My requirement is to add another column 'YellowCategory'. For that I tried to change the query to following:
SELECT c.id, c.customer_name, b.batch_prefix, b.BatchCount, b.InvoiceCount, e.time_of_delivery, e.time_of_delivery_mail, e.time_of_delivery_clock, e.YellowCategory
FROM koll_customers c
INNER JOIN (
SELECT batch_prefix, COUNT(*) AS BatchCount,
SUM (batch_counter) AS InvoiceCount
FROM koll_batchlogs
WHERE
exists_db = 0
and is_checked = 1
and batch_counter > 0
and trunc(created_date) > trunc(sysdate-7)
GROUP BY batch_prefix) b
ON b.batch_prefix=c.customer_prefix
INNER JOIN (
SELECT id, time_of_delivery, time_of_delivery_mail, time_of_delivery_clock, COUNT(b.batch_counter) AS YellowCategory,
FROM koll_customer_export
WHERE to_date(created_date,'DD.MM.RRRR HH24:MI:SS') < to_date(sysdate-time_of_delivery,'DD.MM.RRRR HH24:MI:SS')
GROUP BY b.batch_counter) e
ON e.id = c.id
But then I get "missing expression" error. I guess in last INNER JOIN. Don't know where is the problem... Any help?
Update
With following query, I get b.batch_counter invalid identifier error now.
SELECT c.id, c.customer_name, b.batch_prefix, b.BatchCount,
b.InvoiceCount, e.time_of_delivery, e.time_of_delivery_mail,
e.time_of_delivery_clock, e.YellowCategory
FROM koll_customers c
INNER JOIN (
SELECT batch_prefix, batch_counter, COUNT(*) AS BatchCount,
SUM (batch_counter) AS InvoiceCount
FROM koll_batchlogs
WHERE exists_db = 0 and is_checked = 1
and batch_counter > 0 and trunc(created_date) > trunc(sysdate-7)
GROUP BY batch_prefix
) b
ON b.batch_prefix=c.customer_prefix
INNER JOIN (
SELECT id, time_of_delivery, time_of_delivery_mail,
time_of_delivery_clock,
COUNT(b.batch_counter) AS YellowCategory
FROM koll_customer_export
WHERE to_date(created_date,'DD.MM.RRRR HH24:MI:SS')
< to_date(sysdate- time_of_delivery,'DD.MM.RRRR HH24:MI:SS')
GROUP BY b.batch_counter
) e
ON e.id = c.id
Is this the query you want?
SELECT c.id, c.customer_name, b.batch_prefix, b.BatchCount, b.InvoiceCount,
e.time_of_delivery, e.time_of_delivery_mail, e.time_of_delivery_clock, e.YellowCategory
FROM koll_customers c INNER JOIN
(SELECT batch_prefix, COUNT(*) AS BatchCount, SUM (batch_counter) AS InvoiceCount
FROM koll_batchlogs
WHERE exists_db = 0 and is_checked = 1 and batch_counter > 0 and
trunc(created_date) > trunc(sysdate-7)
GROUP BY batch_prefix
) b
ON b.batch_prefix = c.customer_prefix INNER JOIN
(SELECT id, time_of_delivery, time_of_delivery_mail, time_of_delivery_clock,
COUNT(*) AS YellowCategory,
FROM koll_customer_export
WHERE to_date(created_date, 'DD.MM.RRRR HH24:MI:SS') < to_date(sysdate-time_of_delivery,'DD.MM.RRRR HH24:MI:SS')
GROUP BY id, time_of_delivery, time_of_delivery_mail, time_of_delivery_clock
) e
ON e.id = c.id;
It is impossible for me to say if this is what you really need. But I think the query will at least compile so you can run it.. The where clause in the e subquery looks really strange. Why would you be converting a date column into a date column using to_date()?
You typed one comma too much at the end of the SELECT list inside the last INNER JOIN.
hello i have 2 queries and i wanna join together but i don't know how...
SELECT *, count(*) as invii
FROM professionisti JOIN preventivi_invii ON
professionisti.email=preventivi_invii.email
GROUP BY professionisti.email
HAVING invii> 300
SELECT *, count(*) as acquisti
FROM professionisti JOIN contatti_acquistati ON
professionisti.email=contatti_acquistati.email
GROUP BY professionisti.email
HAVING acquisti> 5
the problem for me is multiple count and the group by with same column.
thank u
How about the below query. You would just change the WHERE clause to meet your needs.
SQL Fiddle Example:
SELECT * FROM
(
SELECT p.email,
CASE WHEN ISNULL(m1.invii) THEN 0 ELSE m1.invii END AS invii,
CASE WHEN ISNULL(m2.acquisti) THEN 0 ELSE m2.acquisti END AS acquisti
FROM professionisti p
LEFT JOIN
(
SELECT pp.email, COUNT(*) AS invii
FROM preventivi_invii pp
GROUP BY pp.email
) AS m1 ON p.email = m1.email
LEFT JOIN
(
SELECT c.email, COUNT(*) AS acquisti
FROM contatti_acquistati c
GROUP BY c.email
) AS m2 ON p.email = m2.email
) AS mm
WHERE mm.invii = 0
OR mm.acquisti = 0;
Or you could use:
SELECT * FROM
(
SELECT p.email,
(
SELECT
CASE WHEN ISNULL(COUNT(*)) THEN 0 ELSE COUNT(*) END
FROM preventivi_invii pp
WHERE pp.email = p.email
) AS invii,
(
SELECT
CASE WHEN ISNULL(COUNT(*)) THEN 0 ELSE COUNT(*) END
FROM contatti_acquistati c
WHERE c.email = p.email
) AS acquisti
FROM professionisti p
) AS mm
WHERE mm.invii = 0
OR mm.acquisti = 0
How can I Optimize this following query:
SELECT
MONTH('1' + LEFT(Datename(month,visitDate),3) +'00') AS MONTH_NUMBER ,
VisitMonth = LEFT(Datename(month,visitDate),3)
,TotalVisits = Count(v.VisitID)
,TotalVisits_with_StandardReport = Count(CASE WHEN v.ReportStandard NOT IN (0,9) THEN v.ReportStandard END)
,TotalVisits_with_FeedbackReport = Count(CASE WHEN v.DiscrepancyType IN (2,5) THEN v.DiscrepancyStatus END)
,Perc =
CAST(100 - ISNULL(CAST((Count(CASE WHEN v.DiscrepancyType IN (2,5) THEN v.DiscrepancyType END) * 1.0 / Count(CASE WHEN v.ReportStandard NOT IN (0,9) THEN v.ReportStandard END)) * 100 AS FLOAT),0) AS NUMERIC(10,2))
,VisitAssignmentID_with_FeedbackRpt = STUFF (( SELECT ', ' + CAST(v2.AssignmentID AS VARCHAR) from Visits v2
INNER JOIN
Assignments a2 ON a2.AssignmentID = v2.AssignmentID
WHERE
DATENAME(MONTH,v.VisitDate) = DATENAME(MONTH,v2.VisitDate)
AND a2.ClientID IN (22,33) AND v2.DiscrepancyType IN (2,5)
GROUP BY V2.AssignmentID
FOR xml path('')), 1, 2, '')
FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID
WHERE a.ClientID IN (22,33)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'
GROUP BY DATENAME(MONTH,v.VisitDate)
ORDER BY MONTH_NUMBER
Result
Second query which i tried to simplify and optimize (but query results are not same)
I have tried to optimize the query and tried to simply the stuff inner query but i am not getting the results i want. It has reduced the total execution time though but results are not same.
WITH ALL_CTE(MONTH_NUMBER,VisitMonth,VisitID,AssignmentID,ReportStandard,DiscrepancyStatus,DiscrepancyType,VisitA ssignmentID_with_FeedbackRpt)
AS
-- Define the CTE query.
(
SELECT
MONTH('1' + LEFT(Datename(month,visitDate),3) +'00') AS MONTH_NUMBER ,
VisitMonth = LEFT(Datename(month,visitDate),3)
,v.VisitID, v.AssignmentID , v.ReportStandard , v.DiscrepancyStatus, v.DiscrepancyType
,VisitAssignmentID_with_FeedbackRpt =
STUFF (( SELECT ', ' + CAST((CASE WHEN DiscrepancyType IN (2,5) THEN v.AssignmentID END) AS VARCHAR)
FOR xml path('')), 1, 2, '')
FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID
WHERE a.ClientID IN (22,33)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'
group by v.AssignmentID,visitDate,VisitID,ReportStandard,DiscrepancyStatus,DiscrepancyType
)
-- Define the outer query referencing the CTE name.
SELECT
MONTH_NUMBER
,VisitMonth
,COUNT(VisitID)
,TotalVisits_with_StandardReport = COUNT(CASE WHEN ReportStandard NOT IN (0,9) THEN ReportStandard END)
,TotalVisits_with_FeedbackReport = COUNT(CASE WHEN DiscrepancyType IN (2,5) THEN DiscrepancyStatus END)
,isnull(VisitAssignmentID_with_FeedbackRpt,0)
FROM ALL_CTE
GROUP BY MONTH_NUMBER,VisitMonth,VisitAssignmentID_with_FeedbackRpt
Client Stats
I think the only real optimization you can do here is make sure that you have an index on AssignmentID so that the inner join is quicker. All the other parts are pretty irrelevant, they are just conversions handled in memory.