I was hoping for some help on how I can improve the query below which is taking an abosolute age to execute.
I'm aware it's the LEFT JOIN
that's causing the statement to run so slowly but I have no idea how else I could run the query to improve the performance and return the required results.
Query
SELECT
s.id, s.first_name, s.last_name, COUNT(a.AbsenceId)
FROM ((
dbo_ds_staff AS s
INNER JOIN dbo_ds_team_staff_member AS tsm ON s.id=tsm.staff_id
)
INNER JOIN dbo_ds_team_leader AS tl ON tsm.team_id=tl.team_id
)
LEFT JOIN ct_adt_Absence AS a ON s.id=a.StaffId
WHERE
tl.staff_id=2169
And tsm.start_date<NOW()
And (
tsm.end_date>=NOW()
Or tsm.end_date Is Null
)
And tl.start_date<NOW()
And (
tl.end_date>=NOW()
Or tl.end_date Is Null
)
GROUP BY s.id, s.first_name, s.last_name
ORDER BY s.first_name, s.last_name;
If there's any further information I can give to assist, please let me know! Thanks
As suggested in the comments to the question, a pass-through query in Access might speed things up by pushing the processing of the SQL Server tables onto SQL Server itself. For example, a pass-through query named [ptqStaffList] with SQL
SELECT
s.id, s.first_name, s.last_name
FROM
dbo.ds_staff AS s
INNER JOIN
dbo.ds_team_staff_member AS tsm
ON s.id=tsm.staff_id
INNER JOIN
dbo.ds_team_leader AS tl
ON tsm.team_id=tl.team_id
WHERE tl.staff_id=2169
AND tsm.start_date < CURRENT_TIMESTAMP
AND (tsm.end_date >= CURRENT_TIMESTAMP OR tsm.end_date IS NULL)
AND tl.start_date < CURRENT_TIMESTAMP
AND (tl.end_date >= CURRENT_TIMESTAMP OR tl.end_date IS NULL)
...which looks like this in Access...
...returns:
id first_name last_name
-- ---------- ---------
1 Gord Thompson
We can then use that in a regular SELECT query with the local Access table
SELECT
s.id,
s.first_name,
s.last_name,
COUNT(a.AbsenceId) AS AbsenceCount
FROM
ptqStaffList AS s
LEFT JOIN
ct_adt_Absence AS a
ON s.id=a.StaffId
GROUP BY s.id, s.first_name, s.last_name
ORDER BY s.first_name, s.last_name;
returning
id first_name last_name AbsenceCount
-- ---------- --------- ------------
1 Gord Thompson 1
SELECT s.*, COUNT(a.AbsenceId)
FROM
(SELECT s.id, s.first_name, s.last_name
FROM ((dbo_ds_staff AS s
INNER JOIN dbo_ds_team_staff_member AS tsm ON s.id=tsm.staff_id)
INNER JOIN dbo_ds_team_leader AS tl ON tsm.team_id=tl.team_id)
WHERE tl.staff_id=2169 And tsm.start_date<NOW() And (tsm.end_date>=NOW() Or tsm.end_date Is Null) And tl.start_date<NOW() And (tl.end_date>=NOW() Or tl.end_date Is Null)
GROUP BY s.id
ORDER BY s.first_name, s.last_name) as s
LEFT JOIN ct_adt_Absence AS a ON s.id=a.StaffId
GROUP BY s.id
I would select users first and then add the LEFT JOIN to count absence.
Also I don't see why you need the grouping by first_name and last_name
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.