I want to improve my search performance mysql - 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

Related

how can i display the name of a professional from a patient's appointment?

I have this four tables:
One for users, other for professionals, other for patients y another for appointments. I want to get the name of professional from patient's appointment.
I try this:
SELECT appointments.date, appointments.start_time, appointments.indication, professionals.medical_box
FROM appointments
INNER JOIN patients ON appointments.id_patient = patients.id
INNER JOIN users ON users.id = patients.id_user
INNER JOIN professionals ON professionals.id = appointments.id_professional
WHERE users.id = 14
ORDER BY appointments.date DESC, appointments.start_time ASC
And I get all correctly, but when I try to show users.name, the name that I get is the patient name, no the professional name, I want the professional name from that patient appoinment. What will be the sql query?
It looks like to get the professionals name you need to also join the user table on the professional.
Add an alias for the second join onto the users table and reference that when displaying your fields.
SELECT appointments.date, appointments.start_time, appointments.indication, professionals.medical_box, usersProf .name
FROM appointments
INNER JOIN patients ON appointments.id_patient = patients.id
INNER JOIN users ON users.id = patients.id_user
INNER JOIN professionals ON professionals.id = appointments.id_professional
INNER JOIN users as usersProf ON usersProf .id = professionals.id_user
WHERE users.id = 14
ORDER BY appointments.date DESC, appointments.start_time ASC

How do you do multiple joins three joined tables to a fourth table in MYSQL

The database schema for this question is located here: db fiddle
I am trying to do the following:
Join table A (group table) to table J (grouprooms)
Join table B (room table) to table J (grouprooms)
Finally Join table C (users) table A - note table A already joined to J
I have written a query that accomplishes steps 1 and 2 but can't figure out how to join the users table to the group table.
Here's the query I have so far:
select rooms.room_name, groups.group_name, groups.group_ID
from grouprooms
left join rooms on grouprooms.room_ID = rooms.room_ID
left join groups on grouprooms.group_ID = groups.group_ID;
You could just add another LEFT JOIN to your query to link in table users :
select rooms.room_name, groups.group_name, users.name
from grouprooms
left join rooms on grouprooms.room_ID = rooms.room_ID
left join groups on grouprooms.group_ID = groups.group_ID
left join users on grouprooms.group_id = users.group_id
See your updated db fiddle :
grouproom 6 is showing no user because there is no user in group 3 (OPERATIONS)
grouproom 7 is not linked to a group, hence it has no group name and no user

Join two tables query

I have two tables users and linkage. I am creating a link between one user to another. Means user A will be linked to user B and vise versa.
Now I want to get the details of linked users for a particular entered user_id. Means If user A is finding his linked Id's then the details of linked id's should be seen.
Linkage has three columns its id, user_id and linked_contact_id.
Users has columns as user_id, user_name,pass etc..
I tried one join but I only get the linked Id's from this not the details of id's.
SELECT * FROM Users INNER JOIN linkage ON linkage.user_id = Users.user_id WHERE linkage.linked_contact_id = 1
output
user_id linked_contact_id
1 4
1 1
1 5
How can I get this?Please help.. Thank you...
You will need to join on the users table a second time:
SELECT u.*, u2.* FROM Users u
INNER JOIN linkage l ON l.user_id = u.user_id
INNER JOIN Users u2 ON l.linked_contact_id = u2.user_id
WHERE l.linked_contact_id = 1
Please note that as you are selecting the same columns twice (in u.*, u2.*), you will probably have to list out each field with an alias to distinguish between them.
Something wrong on your ratio. But it's okay.
Try LEFT JOIN or RIGHT JOIN
SELECT * users
LEFT JOIN linkage
ON linkage.user_id = users.user_id
WHERE linkage.linked_contact_id = 1
Get Users information
SELECT users.*,
linkage.*,
contact.user_id as contact_user_id,
contact.user_name AS contact_user_name
FROM users
INNER JOIN linkage ON linkage.user_id = users.user_id
INNER JOIN users AS contact ON linkage.linked_contact_id = contact.user_id
WHERE linkage.linked_contact_id = 1
Edit
Here Screenshot of Query Output

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

Find unique values that do not exist in multiple columns and tables

A misconfigured manual import imported our entire AD into our help desk user database, creating a bunch of extraneous/duplicate accounts. Of course, no backup to restore from.
To facilitate the cleanup, I want to run a query that will find users not currently linked to any current or archived tickets. I have three tables, USER, HD_TICKET, and HD_ARCHIVE_TICKET. I want to compare the ID field in USER to the OWNER_ID and SUBMITTER_ID fields in the other two tables, returning the only the values in USER.ID that do not exist in any of the other four columns.
How can this be accomplished?
Do a left join for each relationship where the right table id is null:
select user.*
from user
left join hd_ticket on user.id = hd_ticket.owner_id
left join hd_ticket as hd_ticket2 on user.id = hd_ticket2.submitter_id
left join hd_archive_ticket on user.id = hd_archive_ticket.owner_id
left join hd_archive_ticket as hd_archive_ticket2 on user.id = hd_archive_ticket2.submitter_id
where hd_ticket.owner_id is null
and hd_ticket2.submitter_id is null
and hd_archive_ticket.owner_id is null
and hd_archive_ticket2.submitter_id is null
How about something like:
SELECT id
FROM user
WHERE id NOT IN
(
SELECT owner_id
FROM hd_ticket
UNION ALL
SELECT submitter_id
FROM hd_ticket
UNION ALL
SELECT owner_id
FROM hd_archive_ticket
UNION ALL
SELECT submitter_id
FROM hd_archive_ticket
)
If I understood you situation I would do this:
SELECT a.id FROM user a, hd_ticket b, hd_archive_ticket c WHERE a.id != b.id AND a.id != c.id
You would want to try something like below. Inner query where I am doing Inner join with other 2 tables, will return only those user id which exist in all 3 tables. Then in your outer query I am just filtering out those ID's returned by inner query; since your goal is to get only those USER ID which is not present in other tables.
select ID
FROM USER
WHERE ID NOT IN
(
select u.ID
from user u
inner join HD_TICKET h on u.ID = h.OWNER_ID
inner join HD_ARCHIVE_TICKET ha on u.ID = ha.SUBMITTER_ID
)