MySQL: How to use column alias in left join? - mysql

I am trying to use column alias in the left join but I get sql error with uknown field.
select *, (select SenderId from messages where messageId = 5) as senderId from threads
Left join users where users.id = senderId
This query is quite simple but why is not it working or what is the best way to achieve this ?
I'll really appreciate any contribution.
Thanks

You can't use column aliases in ON or WHERE clauses, because column aliases are assigned to values in the result set, but ON and WHERE are used to create the result set. You need to use another JOIN.
SELECT t.*, m.senderId, u.*
FROM threads AS t
CROSS JOIN messages AS m
LEFT JOIN users AS u ON u.id = m.SenderId
WHERE m.messageId = 5

select t.*, mu.*
from threads as t
Left Join
(select SenderId,users. *
from messages, users
where messages.messageId
= users.id and messsageId = 5) as mu
You need to join threads and mu tables with some id

Related

Easy SQL Query - Aligning foreign keys

I'm taking longer than I expected with an easy Query in MySQL. I think it's gonna be a nested query but I don't see it easily.
I have 3 tables: Users, Comments, and Businesses. Comments have business_id, and user_id as foreign keys.
So I want the result of users.name and comments.review, having the number of the business.
So my First (and wrong) attempt was:
SELECT users.name, users.image, comments.review
FROM reviews JOIN users JOIN businesses
WHERE reviews.user_id=users.id AND reviews.business_id=4;
I want to set that PrimaryKey.user_id is equal to ForeignKey.users.id.
From all of the comments, I want to take these which are from the business_id=4.
It gives me failiure with both 'WHERE' clauses. So not sure if I could fix this with a nested query or maybe with a JOIN clause?
Any help will be appreciated!
Thank you all. [Edited Query]
Try this out and let me know in case of any queries.
select c.name,c.image,a.review
from
comments a
inner join
(select * from buisnesses where buisness_id = 4) b
on a.buisness_id = b.buisness_id
inner join
users c
on a.user_id = c.user_id;
or
select b.name,b.image,a.review
from
comments a
inner join
users b
on a.user_id = b.user_id
where a.buisness_id = 4;
Give this a try:
SELECT
users.name,
users.image,
comments.review
FROM reviews
JOIN users
ON reviews.user_id = users.id
JOIN businesses
ON reviews.business_id = business.business_id
WHERE reviews.business_id=4;
Since you're not using any of the columns from the business table, you could probably drop it from the query:
SELECT
users.name,
users.image,
comments.review
FROM reviews
JOIN users
ON reviews.user_id = users.id
WHERE reviews.business_id=4;

JOIN statement to obtain MAX value

I have two tables (user and I_S) and the I_S table contains a column called score. I need to obtain the highest score and the corresponding user name from the tables.
I used a left join but I keep getting an error saying
Unknown column 'I_S.total_score' in 'field list'
This is the query I used.
SELECT MAX(interview_sessions.total_score)
FROM interview_sessions as sc
LEFT JOIN user as u on sc.user_id = u.user_id
SELECT DISTINCT users.name, I_S.score FROM users
LEFT JOIN I_S ON I_S.user_id = users.user_id WHERE score IN (SELECT MAX(score) FROM I_S)
All users with Max score.
And i think you should write sc.total_score instead interview_sessions.total_score in your query because you use alias
Try using this:
SELECT MAX(sc.total_score)
FROM interview_sessions as sc
LEFT JOIN user as u on sc.user_id = u.user_id
You need an inner query to first determine WHAT is the highest score. Form that, re-join to the interview sessions table on THAT max score. Then join to users to get the names. It is possible multiple people can have a same max score.
select
from
( SELECT MAX(i_s.total_score) as MaxScore
from interview_sessions i_s ) maxAll
JOIN interview_sessions i_s2
on maxAll.MaxScore = i_s2.total_score
JOIN User u
on i_s2.user_id = u.user_id
try this way
select b.*,a.totalscore from user b
inner join( select userid,max(total_score) as totalscore from I_S) a on a.userid=b.userid

Combining join results with an at least function

I'm new to SQL and have managed to pick up the basic functions capably enough, however I'm now trying to find the people with at least two tokens from the results of an inner join:
SELECT
users.[First Name],
users.[Last Name],
IssuedTokens.UserID,
IssuedTokens.TokenID,
Tokens.TokenType
FROM IssuedTokens
INNER JOIN users ON users.ID = IssuedTokens.UserID
INNER JOIN Tokens ON Tokens.number = IssuedTokens.TokenID
GROUP BY IssuedTokens.UserID
HAVING COUNT(*) >= 2
ORDER BY IssuedTokens.UserID
This gives the error:
Column 'Users.First Name' is invalid in the select list because it is
not contained in either an aggregate function or the GROUP BY clause.
I'm comfortable using functions on pre-existing tables, but have not seen how to manipulate the results of a join. If anyone could help it would be much appreciated.
You can do a separate aggregation -- before the join -- to get the users with multiple tokens. Then, the rest of the query doesn't need an aggregation:
SELECT u.[First Name], u.[Last Name], u.UserID, it.TokenID, t.TokenType
FROM IssuedTokens it INNER JOIN
users u
ON u.ID = it.UserID INNER JOIN
Tokens t
ON t.number = it.TokenID INNER JOIN
(SELECT it.UserId
FROM IssuedTokens it
GROUP BY it.UserId
HAVING COUNT(*) >= 2
) itu
ON itu.UserId = it.UserId
ORDER BY it.UserID;

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.

MYSQL JOIN syntax How to Join Three Tables

The following query does what I want. It returns all the resuls in the users table and then if there is a match in the details tble, returns the relevant data
users
id|username
details
id|userid|firstname|lastname
$sql = "SELECT u.*, d.*
FROM `users` u
LEFT JOIN `details` d on
u.id = d.userid
ORDER BY $strorder";
However, when I try to join an additonal table where I want to do the same thing--return all the results of the users table and if there is a match in the third table, return the relevant data (total followers of this user)--it only returns one record.
3rd table
follow
id|followerid|followedid
$sql = "SELECT u.*, d.*, COUNT(f.id)
FROM `users` u
LEFT JOIN `details` d on
u.id = d.userid
LEFT JOIN `follow` f on
u.id = f.followedid
ORDER BY $strorder";
Can anyone see what I am doing wrong? Thanks in advance for any suggestions.
Many thanks.
Try to avoid * to select fields, it will be clearer to group your datas (even if mysql is quite permissive with groupings).
When you have an aggregate function (like COUNT, SUM), the other "non aggregated" requested fields should be in a GROUP BY clause.
Mysql don't force you to GROUP BY all the fields, but... I think it's quite a good habit to be "as ANSI as possible" (usefull when you use another DBMS)
SELECT u.id, u.username, d.firstname, d.lastname, count(*) as numberfollowers
FROM user u
LEFT JOIN details d on u.id = d.userid
LEFT JOIN follow f on u.id = f.followedid
GROUP BY u.id, u.username, d.firstname, d.lastname --or just GROUP BY u.id with Mysql
ORDER BY count(*) desc
COUNT being an aggregate function, when selected with other columns, requires you to group your results by those other columns in the select list.
You should rewrite your query with columns that you want to select from users and details and group by those columns.