Reputation: 5424
I am trying to convert below query via Joins,
SELECT DISTINCT req.*
FROM request req
WHERE (req.user_id IN (
SELECT id from user where id in (SELECT user_id FROM team_member team WHERE team.team_id IN ('344', '723')) and user.active = 1
)
OR req.user_id IN (
SELECT id from user where id in (SELECT approved_employee_id from approver where approver_id = '269') and user.active = 1
))
AND req.status = 'pending';
returns 124 records.
I have wrote below query via joins but doesn't work,
SELECT DISTINCT req.*
FROM request req
LEFT JOIN user u ON u.id = req.user_id AND u.active = 1
LEFT JOIN team_member team ON team.user_id = u.id AND team.team_id IN ('344', '723')
LEFT JOIN approver app ON app.approver_id = u.id AND app.approver_id = '269'
AND req.status = 'pending';
returns more than 500 records.
two issue with this joins, it includes those requests too where status is not pending.
Below is the schema
I have below tables
tbl_approver =
id,
approver_id (FK tbl_user),
approver_team_id (FK tbl_team),
approved_employee_id (FK tbl_user)
tbl_team_mambers =
id,
team_id (FK),
user_id (FK)
tble_user =
id,
email,
username
active
tbl_request =
id,
user_id,
status
Note : as an approver, i can be member of many teams but only approver of some team. or some employee too.
Query wanted : as an approver i want all request of my teams whom i am approver.
Upvotes: 0
Views: 51
Reputation: 2005
For correct results of join
's you need to any joined "table" return only one row for user_id. And do not use left
if needed only rows existing in all tables.
SELECT req.*
FROM request req
JOIN user ON user.id=req.user_id
JOIN (
SELECT distinct approved_employee_id as user_id from approver where approver_id = '269'
UNION
SELECT distinct user_id FROM team_member team WHERE team.team_id IN ('344', '723')
) A ON req.user_id=A.user_id
where user.active = 1
AND req.status = 'pending';
Or, if needed only "real table":
SELECT DISTINCT req.*
FROM request req
JOIN user u ON u.id = req.user_id AND u.active = 1
LEFT JOIN team_member team ON team.user_id = u.id AND team.team_id IN ('344', '723')
LEFT JOIN approver app ON app.approver_id = u.id AND app.approver_id = '269'
WHERE req.status = 'pending'
AND (team.user_id is not null OR app.approver_id is not null)
Upvotes: 1
Reputation: 291
Watch the LEFT JOIN
syntax, here's the visual expression of joins
SELECT DISTINCT req.*
FROM request req
LEFT JOIN user u ON u.id = req.user_id AND u.active = 1
...
This will select all distinct records from request
, and JOIN
them to user. The join_condition
after ON
will only affect the join relation.
If there is no matching row for the right table in the ON or USING part in a LEFT JOIN, a row with all columns set to NULL is used for the right table.
Join syntax from Mysql Documentation
If you really want to use LEFT JOIN
to filter all record from request
, consider moving the condition_expr
to WHERE
SELECT DISTINCT req.*
FROM request req
LEFT JOIN user u ON u.id = req.user_id
...
WHERE u.active = 1
AND ...
If you only need request
that satisfies the join condition to user, you should consider use Join
rather than LEFT JOIN
.
Upvotes: 0