sql complex join - mysql

I have the three related tables that i would like to retrieve data from using joins: tbl_accounts containing the account details of users, tbl_users containing the personal details of users and tbl_t_records that contains the transaction details of all users.
In the tbl_accounts i have a foreign key column holder that helps link it to the tbl_users and in the tbl_t_records I have the foreign key columns oaccount and daccount each linking to tbl_accounts but the oaccount stores the details for the account from which the transaction originated while daccount stores the details for the account to which the transaction is destined
here is the snippet fro the tbl_accounts table
Here is the one for tbl_users
This is the one for tbl_t_records
I would like to create a query that return the name of a sender, receiver and the transaction id using joins.
so far this is what I have tried
SELECT tbl_t_records.id transaction_id,
CONCAT(tbl_users.lname,tbl_users.othername)as sender,
amount,
CONCAT(tbl_users.lname,tbl_users.othername)as receiver
FROM tbl_t_records
INNER JOIN tbl_accounts on oaccount = tbl_accounts.id
INNER JOIN tbl_users ON tbl_accounts.holder = tbl_users.id
this does not give me the details of the destination account rather it only presents the data fro the sender that it uses as the same for the reciever as shown here
What am I doing wrong?

You can join several times, as follows:
select
r.id transaction_id,
concat(u1.lname, u1.othername) sender,
concat(u2.lname, u2.othername) receiver,
r.amount
from tbl_t_records r
inner join tbl_accounts a1 on a1.id = r.oaccount
inner join tbl_users u1 on u1.id = a1.holder
inner join tbl_accounts a2 on a2.id = r.daccount
inner join tbl_users u2 on u2.id = a2.holder
This query starts from the transaction table and then follows the relationships related to oaccount through tbl_accounts (aliased a1) to tbl_users (aliased u1). Another series of joins starts from daccount and brings the related user data (aliases a2/u2).

You just need multiple joins -- a separate set for each name:
SELECT r.*,
CONCAT(uo.lname, uo.othername) as sender,
CONCAT(ud.lname, ud.othername) as receiver
FROM tbl_t_records r JOIN
tbl_accounts ao
ON r.oaccount = ao.id JOIN
tbl_users uo
ON ao.holder = uo.id JOIN
tbl_accounts ad
ON r.daccount = ad.id JOIN
tbl_users ud
ON ad.holder = ud.id;

Related

sql query using results of prior query

How can I query a table and pull out same column info from foreign keys that reference the same table? "SELECT name FROM users INNER JOIN gifts ON to=id WHERE id=1;" will get me the first part but I am unsure on how to get the second part.
You can join the users table twice:
select
u1.name `from`,
u2.name `to`
from gifts g
join users u1 on g.`to` = u1.id
join users u2 on g.`from` = u2.id
where u1.id = 1;

MySQL alias a query for use in another query

My title isn't great, but let me explain my situation. I have a jobs table. The jobs table has 2 foreign keys to the users table: sales_rep_id and account_manager_id.
Then I have another table called contact_info with a one to one relationship to the users table.
jobs
-----
sales_rep_id
account_manager_id
...
users
-----
first_name
last_name
contact_info
-----
user_id
home_phone
If I want to do a query where I get the phone number for both people on every job I would do the following:
SELECT reps.home_phone as reps_home, account_managers.home_phone as a_m_home FROM jobs
JOIN
(SELECT * FROM users
JOIN contact_info
ON users.id = contact_info.user_id) reps
ON reps.id = jobs.sales_rep_id
JOIN
(SELECT * FROM users
JOIN contact_info
ON users.id = contact_info.user_id) account_managers
ON account_managers.id = jobs.account_manager_id
Is there anything I can do to create a temporary table with the joined data? What is the most efficient way to do this join? For example, what if I had 10 foreign keys in the jobs table to the users table, and I needed the phone_number for all 10?
This should be obtain all the info you need
SELECT j.*
, u1.first_name as sales_rep_first_name
, u1.last_name as sales_reps_last_name
, u2.first_name as manager_first_name
, u2.u1.last_name as manager_last_name
, c1.home_phone as sales_rep_home_phone
, c2.home_phone as manager_home_phone
FROM jobs as j
INNER JOIN contact_info as c1 ON j.sales_rep_id = c1.user_id
INNER JOIN user u1 ON u1.id= c1.user_id
INNER JOIN contact_info as c2 ON j.saccount_manager_id = c2.user_id
INNER JOIN user u2 ON u2.id= c2.user_id;
Define a view that joins user and contact_info.
CREATE VIEW user_contact_info
SELECT u.id, u.first_name, u.last_name, c.home_phone
FROM user AS u
JOIN contact_info AS c ON u.id = c.user_id
Then you can use this as if it's a table.
SELECT reps.home_phone as reps_home, account_managers.home_phone as a_m_home
FROM jobs
JOIN user_contact_info AS reps ON reps.id = jobs.sales_rep_id
JOIN user_contact_info AS account_managers ON account_managers.id = jobs.account_manager_id

MySQL Nest Join

I have a users table which contains the users information (fname, lname...etc) and a invoices table. In the invoices table I have a field called created_id which links to the user.id that created the invoice. I also have a field called staff_id which links to the staff user.id that approved the invoice.
How can I query the first and last name for both the created_id and the staff_id in a single query? Here are a few things I've tried....
SELECT
invoices.*,
users.fname as created_fname,
users.lname as created_lname
FROM
invoices
INNER JOIN users
ON users.id = invoices.created_id;
This works, but it only gets me the person's name that created the invoice. How can I add the staff's name to that as well....
SELECT
invoices.*,
users.fname as created_fname,
users.lname as created_lname,
users2.fname as staff_fname,
users2.lname as staff_lname
FROM invoices, users
LEFT JOIN
invoices,
users AS users2
ON
users.id = invoices.created_id,
users.id = users2.id
That doesn't work, but is closer. Any guidance or examples would be very helpful. Also, if you have any recommendations for good books on learning how to do more advanced MySQL queries that would be helpful too.
You need to join users table twice on table Invoice.
SELECT a.*,
b.fname created_firstName,
b.lname created_LastName,
c.fname staff_firstName,
c.lname staff_LastName
FROM Invoice a
INNER JOIN users b
ON a.created_id = b.id
INNER JOIN users c
ON a.staff_id = c.id
and best thing is you can concatenate their names into one using CONCAT
SELECT a.*,
CONCAT(b.fname, ' ', b.lname) created_fullName,
CONCAT(c.fname, ' ', c.lname) staff_fullName
FROM Invoice a
INNER JOIN users b
ON a.created_id = b.id
INNER JOIN users c
ON a.staff_id = c.id

Joining two tables twice in MySQL. Possible or Not???

The table structures for the tables users,messages are like bellow,
Users - ID, Name
Messages - ID, Sender, Receiver, Message
I want to join two tables twice like joining the messages.sender with users.id and messages.receiver with users.id.
Is it possible to get the result with sender's id, sender's name, receiver's id, receiver's name, message...(etc) in a single query???...
Yes, you can join the tables as many times as needed.
SELECT
sender.ID AS `sender_id`,
sender.Name AS `sender_name`,
receiver.ID AS `receiver_id`,
receiver.Name AS `receiver_name`,
Messages.Message
FROM
Messages
INNER JOIN
Users AS sender
ON
sender.ID = Messages.Sender
INNER JOIN
Users AS receiver
ON
receiver.ID = Messages.Receiver
Yes you can do it by naming an inner join:
select id, s.Name, r.Name from Messages
inner join users as s on (message.sender = s.id)
inner join users as r on (merssage.receiver = r.id)

Multitable SQL join in MySQL

how can i join multiple tables in one query
these are my tables
registration
registrationid
regschedid
studentid
registrationschedule
regschedid
session
sessionid
regschedid
sessiondate
schedules
scheduleid
regschedid
teacherid
faculty
teacherid
fname
I wanted to join them all so that i could get the fname and the session date please help me..
by the way i must specify the registration.studentid so that i could get the actual student
To join multiple tables, you use the same technique as to join 2 tables:
SELECT *
FROM registration
JOIN registrationschedule ON registration.regschedid = regschedid
JOIN student ON registration.studentid = student.studentid
--- etc
SELECT registration.*,registrationschedule.*, session.*,schedules.*,faculty.*
FROM registration
LEFT JOIN registrationschedule on registration.regschedid = registrationschedule.regschedid
LEFT JOIN session on session.regschedid = registrationschedule.regschedid
LEFT JOIN schedules on schedules.regschedid = session.regschedid
LEFT JOIN faculty on faculty.teacherid = schedules.teacherid
WHERE registrationid = 1;
SELECT * FROM registration
JOIN registrationschedule ON registration.regschedid=regschedid
JOIN session ON registration.regschedid=session.regschedid
JOIN schedules ON regschedid.regschedid=regschedid
JOIN faculty ON schedules.teacherid = faculty.techerid
WHERE student.id = ?