Select different values from one table based on another table - mysql

So, the two tables in question:
userinfo: id(PK), users_id(FK to users table), name, surname
doctorpatient: id(PK), doctor_id(FK to users table), patient_id(FK to users table)
The idea is each doctor is assigned a few patients via the doctorpatient table. What I want to do is return an array of arrays, where each of the inner arrays contains this:
users_id(doctor), name(doctor), surname(doctor), users_id(patient), name(patient), surname(patient)
Can this even be done using purely SQL? I tried this:
SELECT userinfo.users_id,
userinfo.name,
userinfo.surname,
u2.users_id,
u2.name,
u2.surname
FROM doctorpatient
RIGHT OUTER JOIN userinfo
ON doctorpatient.doctor_id = userinfo.users_id
LEFT OUTER JOIN userinfo AS u2
ON doctorpatient.patient_id = u2.users_id
but no matter what combination of joins I try, it never comes out right. I tried getting the data in three separate queries and then somehow get the result I need using PHP, but I got nowhere with that.
Edit: What I want is this:
array(
subarray1(patient_id1,
patient_name1,
patient_surname1,
doctor_id1,
doctor_name1,
doctor_surname1)
subarray2(patient_id2,
patient_name2,
patient_surname2,
doctor_id1,
doctor_name1,
doctor_surname1)
etc...
where one doctor can have multiple patients. What my query gets me looks something like this:
array(
subarray1(patient_id1,
patient_name1,
patient_surname1,
)
subarray2(patient_id2,
patient_name2,
patient_surname2,
)
etc...
But most of the data is null.

I think a simple JOIN may be sufficient. The OUTER JOINs appear to be causing the null values because it tries to treat the doctors as patients.
SELECT u1.users_id AS doctor_id,
u1.name AS doctor_name,
u1.surname AS doctor_surname,
u2.users_id AS patient_id,
u2.name AS patient_name,
u2.surname AS patient_surname
FROM doctorpatient AS d JOIN userinfo AS u1 ON d.doctor_id = u1.users_id
JOIN userinfo AS u2 ON d.patient_id = u2.users_id

Try this:
SELECT
u.id as user_id,
u.name as user_name
u.surname as user_usrname
d.id as doc_id,
d.name as doc_name,
d.surname as doc_surname
FROM doctorpatient as dp
LEFT JOIN userinfo as u ON (dp.pacient_id = u.id)
LEFT JOIN userinfo as d ON (dp.doctor_id = d.id)

Related

join sql query based on value of another table (in one query)

Let's say that I have two tables A and B where
A is table countries with columns id, name, created, modified
that contains a bunch of countries
And B is table users with columns id, first_name, last_name, email, country_id, created, modified
that contains a bunch of users linked to countries via foreign key country_id
What is the most efficient query to get all the countries that don't have a user with email address "myemail#test.com" associated to it?
I tried something like the following but that didn't work:
SELECT DISTINCT
c.*
FROM
countries c
LEFT JOIN
users u ON u.country_id = c.id
WHERE
u.email <> 'myemail#test.com'
Thanks for any help
NOTE I also tried putting the condition on the email column in the ON clause that didn't work either
A left join is fine, you just need to set it up correctly:
SELECT c.*
FROM countries c LEFT JOIN
users u
ON u.country_id = c.id AND u.email = 'myemail#test.com'
WHERE u.country_id IS NULL;
In terms of performance, this should be pretty similar to NOT EXISTS and NOT IN (although I do not recommend the latter because it has different behavior when there are NULL values).
When you say "that don't have a user with email address "myemail#test.com"",
do you mean no email address -or- not that exact email address?
Updated
Then this should do:
SELECT DISTINCT c.*
FROM countries c
LEFT JOIN users u ON u.country_id = c.id and u.email = 'myemail#test.com'
WHERE u.country_id is null
Which I believe is what Gordon already had.
Updated Again
In that case, try:
SELECT DISTINCT c.*
FROM countries c
INNER JOIN users u ON u.country_id = c.id and ISNULL(u.email, '') = ''
This looks for Null or Empty String email adresses all others are excluded from the join and therefore from the result set.
I hope this helps.

getting common joins for every combination of entries from a table

I have a table of users with userid and username.
Another table has a list of interests, with interestid and name.
A third table is a join table, with userid and interestid.
For each pair of users, I want to get the count of interests they have in common. I've tried a lot of things, the most recent is this:
SELECT u1.username AS me, u2.username AS you, COUNT(j.interestid) AS commoninterests
FROM users u1, users u2
INNER JOIN interests_join j
ON u1.id = j.id
WHERE u1.id != u2.id
GROUP BY u1.name
I just can't get a working query on this. Any help?
This is a self join on interests_join:
select ij1.userid, ij2.userid, count(*)
from interests_join ij1 join
interests_join ij2
on ij1.interestid = ij2.interestid and
ij1.userid < ij2.userid
group by ij1.userid, ij2.userid;
Note: this version only brings back the ids and only one pair for two users: (a, b) but not (b, a).
Now, this gets trickier if you want to include user pairs that have no common interests. If so, you need to first generate the user pairs using a cross join and the bring in the interests:
select u1.username, u2.username, count(ij2.userid)
from users u1 cross join
users u2 left join
interests_join ij1
on ij1.userid = u1.userid left join
interests_join ij2
on ij2.userid = u2.userid and
ij1.interestid = ij2.interestid
group by u1.username, u2.username;

MySQL LEFT JOIN with WHERE returns NULL

Trying to JOIN a few tables to supply the user some information on other users he subscribed to this session.
There is a list of other users with their pictures
this works:
SELECT DISTINCT profile_picupload.imageFull, goals_list.goal, goal03.other,
users.username, users.email FROM profile_picupload
JOIN anal_muses
ON anal_muses.username = profile_picupload.username
JOIN goal03 ON goal03.username = anal_muses.username
JOIN goals_list ON goal03.goal=goals_list.id
JOIN users ON users.email = anal_muses.username
it gives me the desired list.
But - i need the list from anal_muses for this session only - so i changed the code to this:
SELECT DISTINCT profile_picupload.imageFull, goals_list.goal, goal03.other,
users.username, users.email FROM profile_picupload
right JOIN anal_muses
ON anal_muses.username = profile_picupload.username
AND anal_muses.sessionId='$sessionId'
JOIN goal03 ON goal03.username = anal_muses.username
JOIN goals_list ON goal03.goal=goals_list.id
JOIN users ON users.email = anal_muses.username
table profile_picupload - holds only one picture for each user
while table anal_musers holds many rows for each user ( depends on the number of people he subscribed to)
so when i added AND anal_muses.sessionId='$sessionId' I needed to change the first join to RIGHT JOIN
but now i get a list with NULL values for profile_picupload .imageFull
.....
is there a way around this?
Thank you :-)

Get data from multiple tables in MySQL

Table 1 :- tbl_contacts
Fields
user_id
contact_id
first_name
last_name
Table 2 :- tbl_phone_details
Fields
contact_id
phone_number
phone_type
Table 3 :- tbl_email_details
Fields
contact_id
email_address
email_type
QUERY -
SELECT
tbl_contacts.*, tbl_email_details.*, tbl_phone_details.*
FROM
tbl_contacts, tbl_email_details,
tbl_phone_details
WHERE
tbl_contacts.user_id = '1'
I want to get first_name, last_name, Phone and Email details of particular user_id. I have used above query but its giving me repeated results and I am having less knowledge on DB queries like JOIN and INNER QUERY.
If anyone has any idea, please kindly help.
OUTPUT NEEDED:-
contact_id, first_name, last_name, phone_number, phone_type, email_address, email_type
(Here email and phone number can have 1 or more values for particular users).
Try like this
If you want to retrieve data for particular ID
SELECT T.contact_id,
T.first_name,
T.last_name,
P.phone_number,
P.phone_type,
E.email_address,
E.email_type
FROM tbl_contacts T LEFT JOIN tbl_phone_details P ON
T.contact_id = P.contact_id
LEFT JOIN tbl_email_details E ON
T.contact_id = E.contact_id
WHERE T.contact_id = #contact_id
If you want to retrieve all data
SELECT T.contact_id,
T.first_name,
T.last_name,
P.phone_number,
P.phone_type,
E.email_address,
E.email_type
FROM tbl_contacts T LEFT JOIN tbl_phone_details P ON
T.contact_id = P.contact_id
LEFT JOIN tbl_email_details E ON
T.contact_id = E.contact_id
SELECT tbl_contacts.*, tbl_email_details.*, tbl_phone_details.* FROM
tbl_contacts, tbl_email_details, tbl_phone_details WHERE
tbl_contacts.user_id = '1'
You forgot to mention the condition by which you are going to join all the tables!
SELECT c.first_name, c.last_name, p.phone_number, e.email_address
FROM tbl_contacts c, tbl_email_details e, tbl_phone_details p
WHERE tbl_contacts.user_id = '1'
AND c.contact_id = e.contact_id
AND e.contact_id = p.contact_id;
SELECT c.contact_id, c.first_name, c.last_name,
phone.phone_number, phone.phone_type,
email.email_address, email.email_type
FROM tbl_contacts c
LEFT JOIN tbl_email_details email ON c.contact_id = email.contact_id
LEFT JOIN tbl_phone_details phone ON c.contact_id = phone.contact_id
WHERE tbl_contacts.user_id = '1'
Sql queries are easy to learn and write and they are very useful in getting the important data from database. Joins are used to basically fetch the data from two or more tables on the bases of common column in both tables.
Inner Join will select those values that are common in both of the tables.
Left Join will select all the data from the left table and Right Join will select all the data from right table on the basis of id.
These are the basics of SQL and you must know how to fetch accurate data using them.
this is how I would make that request with JOIN ... but there might be some better or faster way to do it.
SELECT first_name, last_name, phone_number, email_address
FROM tbl_contacts
JOIN tbl_phone_details
ON tbl_contacts.contact_id=tbl_phone_details.contact_id
JOIN tbl_email_details
ON tbl_email_details.contact_id=tbl_contacts.contact_id
WHERE tbl_contacts.user_id = '1';
And just so you don't get lost in all the different answers here (which are probably all correct):
you don't need to give an aliase name to your tables (it's just for readability)
you don't need to mention the table names in your column list if the column name is unique (e.g first_name is only in tbl_contacts). Just if you want the contact_id then you should decide which one (e.g. tbl_phone_details.contact_id)
the multi-select as Jayaram proposed, is exactly the same as the JOIN. MySQL handles both queries the same way (I just didn't see his answer when I responded, sorry)

MySQL Join table and count distinct users with no reference in another table

I am trying to count users that are NOT referenced in another table... Right now, I have something along the lines of this:
SELECT COUNT(DISTINCT u.id) FROM users u INNER JOIN orders o ON o.assigned!=u.id;
However, it's returning an invalid value. Any suggestions?
Thank you!
I would suggest using a LEFT JOIN between the two tables and filter the rows without a matching id in the orders table:
select count(u.id)
from users u
left join orders o
on o.assigned = u.id
where o.assigned is null
See SQL Fiddle with Demo
Use a left join and count the rows with no match:
SELECT COUNT(*)
FROM users u
LEFT JOIN orders o
ON o.assigned = u.id
WHERE o.assigned IS NULL
An alternative is to use a NOT IN check:
SELECT COUNT(*)
FROM users
WHERE id NOT IN (SELECT distinct(assigned) FROM orders)
However, in my experience the left join performs better (assuming appropriate indexes).
Simply use this query, assuming that the id is unique in users table:
select count(*) From Users as u where u.id not in (select assigned from orders)
an inner join explicitly looks for rows that match so that isn't the way to go if you are looking for non matched records
assuming that ORDERS.ASSIGNED is matched with USER.ID an outer join could return values from both and show when there aren't matches like so
select
u.id,
o.*
from users u
full outer join orders o
on o.assigned = u.id;
if you only want to know which USER.ID don't have an ORDERS record you could also INTERSECT or use NOT IN () eg
select u.id from users u where id not in (select o.assigned from orders.o);
SELECT COUNT(1) FROM users u
WHERE NOT EXISTS (SELECT * FROM orders o WHERE o.assigned=u.id);
Are you wanting a straight count (like you mentioned), or do you need values returned? This will give you the count; if you want other values, you should take one of the other approaches listed above.