Mysql simulating FULL OUTER JOIN - mysql

I have 2 tables users and orders, I want get users and his orders count
SELECT `users`.*, `orders`.*,count(*) FROM `users` LEFT JOIN orders ON
`users`.`id` = `orders`.`user_id`
UNION SELECT `users`.*, `orders`.*,count(*) FROM users
RIGHT JOIN orders ON `users`.`id` = `orders`.`user_id`
This query select users and order count of users which have order, but not select users who not have orders .
What I want get
user orders
John 5
Thomas 0
Mike 8
What I get
user orders
John 5
Mike 8
How to get also users who not have orders ?

You don't need a full outer join for this. A left outer join should be fine, assuming that all the users in the orders table have a valid reference to the users table:
SELECT u.*, count(o.user_id)
FROM `users` u LEFT JOIN
orders o
ON u.`id` = o.`user_id`
group by u.id

The following query will give you a list of all users and the count of their orders, including 0 if that user has no orders.
Also, are you sure that ORDER_ID is the FK to the user table? That seems counter-intuative to me...
SELECT U.NAME
,COUNT(O.ORDER_ID)
FROM USERS U
LEFT OUTER JOIN
ORDERS O
ON U.ID = O.ORDER_ID
GROUP BY
U.NAME

Related

Why is my join query not giving the expected result for three tables

I have a problem with 3 tables join I'm able to get the desired result for
2 tables which have ids: 138 , 140 , 141
here is my query(Getting Desired Result)
SELECT distinct u.*
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
Here is a demo:http://sqlfiddle.com/#!9/360836/1
Now I want to join the third table to get CONCATENATED skills String like (html,css,mysql,php)
Here is the query (3 results expected, getting only 1)
SELECT distinct u.*,GROUP_CONCAT(uskill.skills) skills
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
left join user_skills uskill on u.user_id = uskill.user_id
Here is a demo:http://sqlfiddle.com/#!9/360836/3
Please help me get 3 results with skills
Thanks in advance!
Below query can solve your problem
SELECT u.*,GROUP_CONCAT(distinct uskill.skills) skills
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
left join user_skills uskill on u.user_id = uskill.user_id
group by u.user_id
you need to use group by to get different user details and add distinct keyword inside GROUP_CONTACT to get distinct skills.
You need to Distinct with Group_Concat like this
SELECT distinct u.*,GROUP_CONCAT(DISTINCT uskill.skills) skills
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
left join user_skills uskill on u.user_id = uskill.USER_ID

Making a query with several JOINS

I am stuck with some SQL query.
I have four tables. Which are connected:
user =>user_account=>acount_profile_entries=>profile_entries
From left to right they are one to many.
user_account has a user_id field as FK.
account_profile_field has user_account_id and profile_entry_id.
Profile_entries has a text field that I need to show for each user (account).
I need to write a query that will show me, all accounts for every user, and its profile entries.
I am sorry if this is confusing, I tried to make it simple
This is what I have done so far. I can show all accounts for every user and this is the point I am stuck with. Last two commented out Joins are not working properly. I believe I am close somewhat, I just need a push :)
SELECT
u.email AS Email,
u.id AS UserId,
ua.id AS UserAccountId,
ua.app_id AS Application
FROM users AS u
INNER JOIN user_accounts ua ON ua.user_id = u.id
-- INNER JOIN account_profile_entries ape ON ape.user_account_id = ua.id
-- INNER JOIN profile_entries as pe ON pe.id = ape.profile_entry_id
limit 10
Try this SQL Query with using LEFT JOIN
Description :- The MySQL LEFT JOIN joins two tables and fetches rows based on a condition, which is matching in both the tables and the unmatched rows will also be available from the table written before the JOIN clause.
SYNTAX
SELECT column_name(s)
FROM table1
LEFT JOIN table2 ON table1.column_name = table2.column_name;
SELECT u.*,
u.id AS UserId,
ua.id AS UserAccountId,
ua.app_id AS Application,pe.* FROM `users` u
LEFT JOIN user_accounts ua ON ua.user_id = u.id
LEFT JOIN account_profile_entries ape ON ape.user_account_id = ua.id
LEFT JOIN profile_entries as pe ON pe.id = ape.profile_entry_id LIMIT 10

Joining 3 Tables With Multiple Column Connections

I am struggling to get the correct syntax for what I need and wondered if anyone could help?
I have 3 tables: users, owneditems and shopitems
From users I need to get userid and city
From owneditems I need to get userid and itemid
From shopitems I need to get id and city
userid on owneditems and users will be the same
itemid on owneditems will be the same as id on shopitems
city on shopitems and users will be the same
What I'm after is to find out which city the users are in and tie up which items they own in that city.
The syntax I tried using was
SELECT users.city, users.id, shopitems.city, shopitems.id, owneditems.itemid, owneditems.userid
FROM users, shopitems, owneditems
WHERE users.city = shopitems.city
AND owneditems.itemid = shopitems.it
AND users.id = owneditems.userid
It is not exactly clear what you are trying to do, but have you tried using a LEFT JOIN instead of the INNER JOIN:
select u.city,
u.id,
s.city,
s.id,
o.itemid,
o.userid
from users u
left join owneditems o
on u.id = o.userid
left join shopitems s
on u.city = s.sity
and o.itemid = s.itemid

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

chat application friend list

I have 3 MySQL tables namely chat_comments, chat_friends and user_details and I want to display a friend list.
My tables:
chat_comments(comment_id,comment,user_id,user_id2,date_added)
chat_friends(user_id,user_id2,approved)
user_details(user_id, mainimage_id, fullname)
To do this, I need a query that will return the needed fields (u.mainimage_id, u.fullname, b.comment, b.user_id) so I can loop through the list to display a table.
SQL so far (help from #Andriy M):
SELECT
cc.comment,
cc.date_added,
u.fullname,
u.mainimage_id
FROM
user_details u
LEFT JOIN
chat_comments cc
INNER JOIN (
SELECT
user_id,
MAX(comment_id) AS maxcomment
FROM chat_comments WHERE user_id=2020 OR user_id2=2020
GROUP BY user_id
) a ON a.user_id = cc.user_id
AND a.maxcomment = cc.comment_id
ON a.user_id = u.user_id
WHERE u.user_id IN (
SELECT user_id2
FROM chat_friends
WHERE user_id = 2020
AND approved = 1
)
The above query returns the last comment made by the logged-in user's friends in conversation not the last comment between the logged-in user and his/her friend regardless of who made it.
I would like it to return the last comment between the logged-in user and their friend individually regardless of who made it. In the chat_messages table, user_id is the sender and user_id2 is the receiver. Hope it makes sense?
Like #imm said in a comment, you need to use an outer join. In case of a left join, the user_details table should become the left side of the join, the right side being the result of your inner join of chat_comments with your a derived table. You'll also need to remove the user_id IN (…) condition from inside the a subselect and re-apply it to the user_details table. Here:
SELECT
cc.comment,
cc.date_added,
u.fullname,
u.mainimage_id
FROM
user_details u
LEFT JOIN
chat_comments cc
INNER JOIN (
SELECT
user_id,
MAX(comment_id) AS maxcomment
FROM chat_comments
GROUP BY user_id
) a ON a.user_id = cc.user_id
AND a.maxcomment = cc.comment_id
ON a.user_id = u.user_id
WHERE u.user_id IN (
SELECT user_id2
FROM chat_friends
WHERE user_id = 2020
AND approved = 1
)
;
Alternatively, you could use a right join. In this case you would just need to move the user_id IN (…) condition, similarly to the LEFT JOIN solution above, and replace the second INNER JOIN with RIGHT JOIN:
SELECT
cc.comment, cc.date_added, u.fullname, u.mainimage_id
FROM
(
SELECT user_id, MAX(comment_id) AS maxcomment
FROM chat_comments
GROUP BY user_id
) a
INNER JOIN
chat_comments cc ON
a.user_id = cc.user_id AND
a.maxcomment = cc.comment_id
RIGHT JOIN
user_details u ON
a.user_id = u.user_id
WHERE u.user_id IN (select user_id2 from chat_friends where user_id=2020 AND approved=1)