mysql left joining same table twice - php

I'm trying to left join the same table twice but it's giving me some problems. I have two tables ee_all and ee_calendar_events that I want to join.
SELECT
u.first_name,
u.last_name,
u.email,
SUM(e1.total_vacation_hours_earned) AS vacation_hours_earned,
SUM(e2.absent_hours)
FROM ee_all AS u
LEFT JOIN ee_calendar_events AS e1 ON u.user_id = e1.sched_user_id
LEFT JOIN ee_calendar_events AS e2 ON u.user_id = e2.sched_user_id AND e2.event_id = 2
WHERE
u.user_id = 23
The vacation_hours_earned column is supposed to return 133, which it does if I take out the second join. But soon as I add it, the query takes forever and the vacation_hours_earned has a value of 2000 or something (which is wrong). My guess is it's summing the row again when I add the second join, but I don't wan't that. I've been trying for a few hours but can't find a way around it, would appreciate any help.

When the rightmost table (the second join) has more than one row corresponding to a row of the table expression to the left, rows of the left-hand table expression are duplicated and count more than once in the SUM. Use subqueries instead.
SELECT
u.first_name,
u.last_name,
u.email,
(
SELECT
SUM(e1.total_vacation_hours_earned)
FROM
ee_calendar_events AS e1
WHERE
u.user_id = e1.sched_user_id
) AS vacation_hours_earned,
(similar) AS absent_hours
FROM
ee_all AS u
WHERE
u.user_id = 23

Using some MySQL syntax, you can just eliminate the second left join and simplify the query;
SELECT
u.first_name,
u.last_name,
u.email,
SUM(e1.total_vacation_hours_earned) AS vacation_hours_earned,
SUM(e1.absent_hours * (event_id=2))
FROM ee_all AS u
LEFT JOIN ee_calendar_events AS e1 ON u.user_id = e1.sched_user_id
WHERE
u.user_id = 23
Demo here.

SELECT
u.first_name,
u.last_name,
u.email,
SUM(e1.total_vacation_hours_earned) AS vacation_hours_earned,
(select SUM(e2.absent_hours) as absenthours from ee_calendar_events AS e2 where u.user_id = e2.sched_user_id AND e2.event_id = 2)
FROM ee_all AS u
LEFT JOIN ee_calendar_events AS e1 ON u.user_id = e1.sched_user_id
WHERE
u.user_id = 23

Related

how to subtract one query result to another query in mysql

this is my first query
SELECT DISTINCT(u.nickname) FROM user u
where u.id IN(SELECT `submission_user`.`user_id` from `submission_user`) AND
u.member_since >= '2015-07-01'
this is my second query
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id
LEFT JOIN submission s ON s.id = su.submission_id
WHERE s.date_time BETWEEN '2017-10-31' and '2018-07-31'
and this is my third query
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id
LEFT JOIN track_user tu ON tu.user_id = u.id
LEFT JOIN track ON track.id = tu.track_id
where track.uploaded_timestamp BETWEEN '2017-10-31' and '2018-07-31'
and after that, I am merging the second and third query result
$ids_reactivated = array_unique(array_merge($track_user, $submit_user));
so my question is that if I want to subtract query one result to merge result means with the (query 2 and 3)i.e in my case: $ids_reactivated
anyone have an idea how to do it ...
I already tried many ways and passed one day...
hope pepls help me thanks
thanks for your hint but i got my answer like this ...
SELECT DISTINCT(u.nickname) FROM user u
where u.id IN(SELECT `submission_user`.`user_id` from `submission_user`) AND
u.member_since >= '2015-07-01'
**and u.nickname not in ($query2)**
UNION
SELECT DISTINCT(u.nickname) FROM user u
where u.id IN(SELECT `submission_user`.`user_id` from `submission_user`) AND
u.member_since >= '2015-07-01'
**and u.nickname not in ($query3)**
Its simple You can make use of union for merging and not in for substraction
Following is the sample
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id LEFT JOIN submission s ON s.id = su.submission_id
WHERE s.date_time BETWEEN '2017-10-31' and '2018-07-31'
**and u.nickname not in ($query1)**
UNION
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id LEFT JOIN track_user tu ON tu.user_id = u.id LEFT JOIN track ON track.id = tu.track_id
where track.uploaded_timestamp BETWEEN '2017-10-31' and '2018-07-31'
**and u.nickname not in ($query1)**
change the $query1 with your query ,it should give the result

How to perform inner join in mysql

I have to write a query such that ,I need to get events whose start date is of 30 min from now.
My conditions are:
1) get the event from events table
2)Join created by of events with id in users table.
3)Comments from comment table with user ser id
But the problem here is if there is no comment for event then the event it self is not coming.If any comment is present it is coming.I dont want this.If comment is not there just fetch it as empty but not hide the total event .Can anyone please help me,.Thanks.
select u.email ,group_members.user_id,users.first_name,u.first_name
as host_name,events.name,events.start_date,comments.comments,c.first_name as
comment_user,comments.id from events
inner join users as u on u.id = events.created_by
inner join comments on events.id = comments.event_id
inner join group_members on events.group_id = group_members.group_id
inner join users as c on comments.from_user = c.id
inner join users on group_members.user_id = users.id
where events.start_date between date_add(now(),interval 1 minute) and date_add(
now(),interval 30 minute)
and group_members.user_status = 2
and events.status = 2
You need a left join to the comments table. I would put that table last in the from clause.
select u.email, gm.user_id, gu.first_name, u.first_name as host_name,
e.name, e.start_date, c.comments, uc.first_name as comment_user,
c.id
from events e inner join
users u
on u.id = e.created_by inner join
group_members gm
on e.events.group_id = gm.group_id inner join
users gu
on gm.user_id = gu.id left join
comments c
on e.id = c.event_id left join
users uc
on c.from_user = uc.id
where e.start_date between date_add(now(),interval 1 minute) and date_add(now(),interval 30 minute) and
gm.user_status = 2 and
e.status = 2;
Once you use a left join on comments, you also need a left join for the from user. I replaced all table names with aliases -- this makes it easier to track which table is used for which purpose.
Use the INNER JOIN Keyword and select the two columns by putting them with keyword ON.
SELECT EMP.EMP_ID, EMP.EMP_NAME, DEPT.DEPT_NAME FROM EMP
INNER JOIN DEPT ON DEPT.DEPT_ID = EMP.DEPT_ID;

my query is taking a long time to execute

I have following query .. in Dev_phones I have 90 000 item in Dev_users 50 000
select `u`.`id` from `Dev_users` as `u`
left join `Dev_user_usergroup_map` as `m` on `u`.`id` = `m`.`user_id`
left join `Dev_phones` as `p` on `m`.`id` = `p`.`acc_id` and `primary`=1
where `u`.`email`='sample#gmail.com' or `u`.`private_number`='sample#gmail.com'
or `m`.`id`='sample#gmail.com' or `p`.`number`='sample#gmail.com' limit 1
query goes to loop and not ending ...
what is problem and how can i write better this query
Just FYI, this query can be rewritten as follows - although I find using OUTER JOIN with OR (or an IN) across several tables in this way very confusing...
SELECT u.id
FROM Dev_users u
LEFT
JOIN Dev_user_usergroup_map m
ON u.id = m.user_id
LEFT
JOIN Dev_phones p
ON m.id = p.acc_id
AND `primary` = 1
WHERE 'sample#gmail.com' IN(u.email,u.private_number,m.id,p.number)
LIMIT 1;

MySQL Two Left Joins Distinguish Same Column

In the following query, I am selecting the one column from users and am expecting a join to take place on both follow_reconciliations user_id and followed_user_id column.
SELECT u.ig_user_id FROM users u
LEFT JOIN follow_reconciliations f ON (f.followed_user_id = u.user_id)
LEFT JOIN follow_reconciliations f2 ON (f2.user_id = u.user_id)
But, I need to know which query the ig_user_id comes from. How can I rename ig_user_id as an alias for each join? What is the best approach to this?
EDIT: Visually, this is how I want the results to return
+------------+---------------------+
| ig_user_id | followed_ig_user_id |
+------------+---------------------+
| 15325 | 5295 |
+------------+---------------------+
This query might be more in the direction of this. It returns the correct results as two rows but they are not renamed as two aliases.
SELECT u.ig_user_id AS ig_user_id FROM users u LEFT JOIN follow_reconciliations f ON (f.user_id = u.user_id)
UNION
SELECT u2.ig_user_id AS followed_ig_user_id FROM users u2 LEFT JOIN follow_reconciliations f2 ON (f2.followed_user_id = u2.user_id)
Second Edit: This does the trick.
SELECT u.ig_user_id AS ig_user_id, u2.ig_user_id AS followed_user_id
FROM follow_reconciliations f
LEFT JOIN users u ON (u.user_id = f.user_id)
LEFT JOIN users u2 ON (f.followed_user_id = u2.user_id)
If I understand correctly (do I?) you only need one join:
SELECT
ig_user_id,
f.followed_user_id as followed_ig_user_id
FROM users u
LEFT JOIN follow_reconciliations f USING (user_id)
This gives me the results I am looking for:
SELECT u.ig_user_id AS ig_user_id, u2.ig_user_id AS followed_user_id
FROM follow_reconciliations f
LEFT JOIN users u ON (u.user_id = f.user_id)
LEFT JOIN users u2 ON (f.followed_user_id = u2.user_id)
If anyone has any performance suggestions, please chime in.
if i understand your question.. i'm sory if wrong..
SELECT u.ig_user_id,xx.followed_user_id FROM users u
LEFT JOIN (SELECT * FROM follow_reconciliations f) as xx ON (xx.followed_user_id = u.user_id)
LEFT JOIN (SELECT * FROM follow_reconciliations f2) as yy ON (yy.user_id = u.user_id)
this query provide you to rename or aliasing every column on table.. :)
CMIIW

mysql query for getting related data from different table for suggested connections

we are developing portal like social network site with different concept...but for doing suggested connections we got strucked in mysql queries...
we are trying to take users with similat data ...
SELECT u.*
FROM educonnect_user u
LEFT OUTER JOIN educonnect_user_qualification q ON u.id = q.user_id
LEFT OUTER JOIN educonnect_user_contact a1 ON u.id = a1.user_id
WHERE q.type_of_institution in
(
SELECT type_of_institution
FROM educonnect_user_qualification qi
WHERE qi.user_id = 3
)
AND q.college in
(
select college
from educonnect_user_qualification qc
where qc.user_id = 3
)
AND q.country in
(
select country
from educonnect_user_qualification qco
where qco.user_id = 3
)
AND a1.country in
(
select country
from educonnect_user_contact cc
where cc.user_id = 3
)
AND a1.state in
(
select state
from educonnect_user_contact cs
where cs.user_id = 3
)
Like this I am joining 10 tables ..but the problem is wherever i gave AND operator no result generated and if i gave OR operator it returns all users ..its the logic these operator will give output which I know..but for this problem i need different suggestions which would work effectively..or else the query can be changed with any other specific operator???
You didn't need all these WHERE IN conditions. You just need where educonnect_user.user_id = 3 since the educonnect_user table is joined with the other two tables educonnect_user_qualification and educonnect_user_contact, therefore the join will insure that for the user with id=3 the fields: type_of_institution, college, country,..( and other fields ) are exists in the two other tables for the same user, But you need to care about what type of join you need depending on what fields you want to select from your tables whether Left, right. So I think the following query what you are looking for:
SELECT u.*
FROM educonnect_user u
LEFT OUTER JOIN educonnect_user_qualification q ON u.id = q.user_id
LEFT OUTER JOIN educonnect_user_contact a1 ON u.id = a1.user_id
where u.user_id = 3
Hope this will help ::
SELECT u.*
FROM educonnect_user u
LEFT OUTER JOIN educonnect_user_qualification q ON u.id = q.user_id
LEFT OUTER JOIN educonnect_user_contact a1 ON u.id = a1.user_id
left join educonnect_user_qualification qi on (q.type_of_institution=qi.type_of_institution and qi.user_id=3)
left join educonnect_user_qualification qc on (q.college=qc.college and qc.user_id=3)
left join educonnect_user_qualification qco on (q.country=qco.country and qco.user_id=3)
left join educonnect_user_contact cc on (a1.country=cc.country and cc.user_id=3)
left join educonnect_user_contact cs on (a1.state=cs.state and cs.user_id=3)

Categories