How to select two joined columns? - mysql

I have a table with two columns:
player1_id and player2_id - they are linked with id's in users table (primary key)
I am trying to select users name using their id's with query below but it gives me two rows instead of one
SELECT users.name, tournaments_results.* FROM tournaments_results JOIN users ON tournaments_results.p1_id = users.id
UNION
SELECT users.name, tournaments_results.* FROM tournaments_results JOIN users ON tournaments_results.p2_id = users.id
how to select users.name as two different columns as name_player_1 and name_player_2 accordingly in one row in result?

You use two joins:
SELECT tournaments_results.*, u1.name, u2.name
FROM tournaments_results tr LEFT JOIN
users u1
ON tr.p1_id = u1.id LEFT JOIN
users u2
ON tr.p2_id = u2.id;
This uses LEFT JOIN, in case one of the columns doesn't match.

Related

Counting and Summing three tables together and get users information with their like counts

I have three tables:
table: users / columns: user_id, email, username
table: activities / columns: object, type, like_count
table: activities2 / columns: object, target_type, subject, type
The like_count in activities table has no problem and I count all of that with this query:
SELECT SUM(activities.like_count) AS likes, users.user_id, users.email, users.username
FROM activities
INNER JOIN users
ON activities.subject = users.user_id
GROUP BY user_id
But there is another count in activities table which is being inserted(NOT UPDATED) each time some other types of posts liked and I counted them by this query:
SELECT activities.subject, activities.object, COUNT(activities.type) AS likes
FROM activities
INNER JOIN activities2
ON activities.object = activities2.object AND activities2.target_type = 'parent'
WHERE activities2.type LIKE 'like_%'
GROUP BY activities2.subject
BUT the problem starts from here when I want to join them together! I want to count like_count + count of likes that inserted in that table(activities2) that contains string of 'like_' and beside this I want to join the subject(in activities table) which is related to user_id in the other table(users).
My last query is this:
SELECT users.user_id, users.email, users.username, activities.object, COUNT(activities.type)+SUM(activities.like_count) AS likes
FROM activities
INNER JOIN activities2
ON activities.object = activities2.object AND activities2.target_type = 'parent'
INNER JOIN users
ON activities.subject = users.user_id
WHERE activities2.type LIKE 'like_%'
GROUP BY users.user_id
The problem is when joining, it fetches the user information not for the one that I want.
In conclusion I want something like this:
user_id------email-----------------username----------object-------likes
2521---------a#b.com---------------abc---------------9578---------3
5484---------c#d.com---------------def---------------8547---------16
8431---------e#f.com---------------ghi---------------4584---------1
And offcourse the result is this but only likes are correct however columns of user_id, email, username that are in users table NOT!
I was wondering if you would help to fix it. I'm really tired of trying and facing to no result :(
users table data:
user_id-------------email---------------username
1-------------------a#b.com-------------abc
2-------------------c#d.com-------------def
3-------------------e#f.com-------------ghi
activities table data:
object----------type----------------like_count------subject
20--------------like_video----------0---------------1
20--------------like_photo----------0---------------2
33--------------like_music----------0---------------3
33--------------some_other_type-----5---------------6
33--------------some_other_type-----8---------------10
activities2 table data:
object------target_type-----subject-----type
20----------parent----------30----------like_video
21----------owner-----------40----------like_audio
22----------parent----------50----------something_not_start_with_like_
I want:
user_id------email-----------------username----------object-------likes
1------------a#b.com---------------abc---------------9578---------(sum of like_count + count of type which has like_ in first characters)
2------------c#d.com---------------def---------------8547---------(sum of like_count + count of type which has like_ in first characters)
3------------e#f.com---------------ghi---------------4584---------(sum of like_count + count of type which has like_ in first characters)
Consider joining the aggregate queries using derived tables and then run your addition calculation in the outer query. Also, below object column is removed from the second aggregate query's GROUP BY clause but still used in JOIN since you need summation at the subject level.
SELECT u.user_id, u.email, u.username, a.`object`, u.likes + a.likes as `total_likes`
FROM
(SELECT SUM(activities.like_count) AS likes, users.user_id, users.email, users.username
FROM activities
INNER JOIN users
ON activities.subject = users.user_id
GROUP BY user_id, users.email, users.username) u
INNER JOIN
(SELECT activities.subject, COUNT(activities.type) AS likes
FROM activities
INNER JOIN activities2
ON activities.object = activities2.object AND activities2.target_type = 'parent'
WHERE activities2.type LIKE 'like_%'
GROUP BY activities2.subject) As a
ON u.user_id = a.subject

Joining 3 tables - If row doesn't exist

I need to join tables
messages_between
users
status
I have this SQL:
SELECT messages_between.*, users.*, status.* FROM messages_between
LEFT JOIN users
ON users.uid = messages_between.user_2
LEFT JOIN status
ON status.uid = messages_between.user_2
WHERE messages_between.user_1 = 123
So this query works fine but the problem is when I don't have a row in messages_between.
The uid is code which is used in columns user_1 or user_2
Any suggestions?
Thanks
[EDIT]
My structures of tables:
users has columns: id, name, password, password_s, uid
status has columns: id, uid, status[if he/she is online or offline]
messages_between has columns: id, user_1, user_2, mid
So I want to show users.name, status.status, messages_between.user_2, messages_between.mid
Is this what you want?
SELECT messages_between.*, users.*, status.*
FROM users LEFT JOIN
messages_between
ON users.uid = messages_between.user_2 and messages_between.user_1 = 123 LEFT JOIN
status
ON status.uid = users.uid;
This keeps all users, providing additional information when there is an appropriate "message between".
You can try the following query. When you need null from the joined tables then you should not add the conditiona in where clause. Either you also check with null or add the conditiona in join clause.
Also you need to change the order of left join, becuase you want to retrive all the recrods from the users table and null values for the missing messages_between records and status records.
SELECT messages_between.*, users.*, status.* FROM messages_between
LEFT JOIN users
ON users.uid = messages_between.user_2 AND messages_between.user_1 = 123
LEFT JOIN status
ON status.uid = messages_between.user_2

SELECT different users from same table in single JOIN

I am currently trying to join a table (tasks) with another table (users). I need to select different rows from the users table based on values in the tasks table:
tasks(user1, user2, user3);
users(id, name, email);
Previously I have linked data using a LEFT JOIN like so:
SELECT * FROM tasks LEFT JOIN users ON tasks.user1 = users.id;
Thats pretty simple, so I have tried using an AND like so:
SELECT * FROM tasks LEFT JOIN users ON tasks.user1 = users.id AND tasks.user2 = users.id;
but that returns the users fields as NULL, which makes sense as tasks.user1 is different to tasks.user2
I am pretty stumped on how to do this now, all suggestions welcome!
You'll need to repeat the join and alias the users table diffeently for each joined column:
SELECT * FROM tasks
LEFT JOIN users u1 ON tasks.user1 = u1.id
LEFT JOIN users u2 ON tasks.user2 = u2.id
...
use this one:
SELECT *
FROM tasks
LEFT JOIN users
ON tasks.user1 = users.id
OR tasks.user2 = users.id;

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.

How to select two additional columns from another table based on values in the main table?

I have a table named maintable with 3 columns: id, userid1 and userid2.
Another table named users is keyed by userid, and has name as a column.
I want to select something along the lines of:
SELECT maintable.*, users.name AS username1, users.name AS username2
FROM maintable, users
WHERE ...
Basically I want to get all the columns in the maintable row, and add two columns at the end that will draw the names for userid1 and userid2 from the users table.
I'm unsure how to format the where clause for a query like this.
You need to join twice with users:
SELECT m.*, u1.name, u2.name
FROM maintable m
INNER JOIN users u1 ON (m.userid1 = u1.userid)
INNER JOIN users u2 ON (m.userid2 = u2.userid)
You can read the documentation about MySQL JOIN Syntax here.
something like this,
select m.*,
(select u1.name from users as u1 where m.userid1 = u1.userid) as username1,
(select u2.name from users as u2 where m.userid2 = u2.userid) as username2
from
maintable as m