Double JOIN to get two different parameters? - mysql

Consider 2 tables: USERS and TASKS for a task delivery app
USERS
userID | email | name
TASKS
userID | designator_userUNIQUE | destination_userUNIQUE
To get the destination_user full name from the users table I am using the following query that works fine:
SELECT *
FROM tasks
INNER JOIN users ON users.userID = tasks.destination_userUNIQUE
WHERE tasks.client='$clientUNIQUE'
ORDER BY tasks.date DESC, tasks.time DESC
However, if I want to get the full name from the designator_userUNIQUE using the below query, it simply generates an sql error (mysql_numrows() expects parameter 1 to be resource).
SELECT *
FROM tasks
INNER JOIN users ON users.userID = tasks.destination_userUNIQUE
INNER JOIN users ON users.name = tasks.designator_user UNIQUE
WHERE tasks.client='$clientUNIQUE'
ORDER BY tasks.date DESC, tasks.time DESC
Any ideas?

You need to give different aliases to each instance of the users table that you join with, to prevent ambiguity.
SELECT *
FROM tasks AS t
INNER JOIN users AS dest ON dest.userID = t.destination_userUNIQUE
INNER JOIN users AS desig ON desig.userID = t.designator_userUNIQUE
WHERE t.client='$clientUNIQUE'
ORDER BY t.date DESC, t.time DESC

Related

I want to improve my search performance mysql

I want to improve my search performance. I want to search the user against the services and specialty. user in listed as per the filter applied either by specialty or by services or can be both.There are 5 tables i want to get the data from all the table
I have below table structure
1) users :- id ,first_name,last_name
2) users_services :- id ,user_id,service_id
3) users_speciality :- id,user_id,specility_id
4) mst_services :- id,name
5) mst_speciality :- id,name
I have used this query to get the result and it works fine.
select u.id,first_name,last_name,location,services.name as service_name,speciality.name as specility_name from users as u
inner join users_services on u.id =users_services.user_id
Inner join mst_services as services on services.id=users_services.service_id
inner join users_speciality on u.id =users_speciality.user_id
Inner join mst_speciality as speciality on speciality.id=users_speciality.service_id WHERE speciality.name ="specificity one"
as per the normalization it seems correct.But when data is more than 1,00,000 that time joining too many table causes may create problem.
what should i do for filter the user according to services and specialty ?
Have you tried like this ?
SELECT users.id,first_name,last_name, mst_services.name as service, mst_speciality.name AS speciality
FROM users
LEFT JOIN users_services ON users.id = users_services.user_id
LEFT JOIN users_speciality ON users.id = users_speciality.user_id
LEFT JOIN mst_services ON service_id = mst_services.id
LEFT JOIN mst_speciality ON speciality_id = mst_speciality.id
WHERE users.id IN
(SELECT user_id FROM users_services
WHERE service_id = (SELECT id FROM mst_services WHERE name = "service one")
UNION ALL
SELECT user_id FROM users_speciality
WHERE speciality_id = (SELECT id FROM mst_speciality WHERE name = "spercial one"))
ORDER BY first_name,last_name,service,speciality

SQL intermediate table having column = max(column)

I have 2 tables: user and review, a one-to-many relationship.
When I execute the following query:
SELECT
user_id,
count(*) totalReviews,
USER . NAME
FROM
review,
USER
WHERE
USER .id = review.user_id
GROUP BY
user_id
I get:
1 2 marius
2 2 daniela
3 1 alin
What I want to do now is to display first 2 users because they have given the most reviews(2).
I tried adding having, if I hardcode having totalReviews=2 it works, but if I write having total = max(total) I get 0 results, while if I'm trying with,
SELECT
*
FROM
(
SELECT
user_id,
count(*) total,
USER . NAME
FROM
review,
USER
WHERE
USER .id = review.user_id
GROUP BY
user_id
) A
WHERE
total = (SELECT max(total) FROM A) `
I get an error (table A doesn't exist)
You would do this with ORDER BY and LIMIT:
SELECT u.id, count(*) as totalReviews, u.name
FROM review r JOIN
user u
ON u.id = r.user_id
GROUP BY u.id, u.name
ORDER BY totalReviews DESC
LIMIT 2;
Notes:
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
Table aliases make the query easier to write and read.
EDIT:
If occurs to me that you want all users with the maximum number of reviews, not exactly 2. Here is one method:
SELECT u.id, COUNT(*) as totalReviews, u.name
FROM review r JOIN
user u
ON u.id = r.user_id
GROUP BY u.id, u.name
HAVING totalReviews = (SELECT COUNT(*)
FROM review r2
GROUP BY r2.user_id
ORDER BY COUNT(*) DESC
LIMIT 1
);
Note that the subquery in the HAVING clause is simpler than the outer query. There is no need to bring in the user name.

get last record of one to many relation

I have two tables
users : id,name
health : id,status,test_date,user_id
health table containing user health history
now i want to get the last health test and user info of a specific user
I tried this query
SELECT users.*, health.* FROM users INNER JOIN health ON users.id=health.user_id
having (max(health.id)) order by users.id desc limit 50
but i failed
Try this:
SELECT users.*, health.* FROM users
INNER JOIN health
ON health.id = (SELECT id FROM health WHERE health.id = users.id ORDER BY id DESC LIMIT 1)
This is an other option:
SELECT U.*, H.*
FROM users AS U
INNER JOIN (
SELECT user_id, MAX(id) AS id
FROM health
GROUP BY user_id
) AS D
ON D.user_id = U.user_id
INNER JOIN health AS H
ON H.id = D.id
NOTE: "D" will result in a DERIVED table and therefore in a faster execution in MySQL 5.7+ or MariaDB 10+.
Reference:
Optimizing Derived Tables and View References
MySQL 5.7: Improved Performance of Queries with Derived Tables

Inner Join Mysql duplicate records

I have following table in my database. I am trying to retrieve data from all three tables.
Table Structure:
User_New
User_ID
Name
Password
Email
User_Group_New
User_ID
Group_ID
Group_New
Group_ID
Group_Name
Issue: I am getting Duplicate records.
Query:
SELECT *
FROM `User_New`
INNER JOIN User_Group_New ON User_Group_New.User_ID = User_New.User_ID
INNER JOIN Group_New ON Group_New.Group_ID = User_Group_New.Group_ID
LIMIT 0, 30
SELECT DISTINCT *
FROM `User_New`
INNER JOIN User_Group_New ON User_Group_New.User_ID = User_New.User_ID
INNER JOIN Group_New ON Group_New.Group_ID = User_Group_New.Group_ID
LIMIT 0, 30
May that solve yours.

MySQL latest unique user chats not working

I'm trying to get latest created datetime for unique user_id. I've got below query but it does not seem to be working....It does not get the latest created time.
SELECT * FROM `chats`
WHERE receiver_id = 1
GROUP BY user_id
ORDER BY created DESC
Is there a reason why?
UPDATE:
Actually I found my answer myself. Please look below. I had to use INNER JOIN for nested searched and filtered result table then find using where clause of that result then left join on that table to get the data I needed!
SELECT c.*, users.username
FROM chats c
INNER JOIN(
SELECT MAX(created) AS Date, user_id, receiver_id, chat, type, id
FROM chats
WHERE receiver_id = 1
GROUP BY user_id ) cc ON cc.Date = c.created AND cc.user_id = c.user_id
LEFT JOIN users ON users.id = c.user_id
WHERE c.receiver_id = 1
You should use a MAX aggregate function -
SELECT user_id, MAX(created) latest_datetime FROM chats
GROUP BY user_id;
Try this query, it will show all users and latest created datetime.