[Yes, I've searched for an answer for this here and in google but this is a little difficult to query for.]
(MySQL database.)
messages table:
messageid
senderid
recipientid
people table:
personid
name
I wish to issue a query that returns the following:
messageid sender_name recipient_name
1 larry jane
2 mark alice
etc.
The following doesn't do it, and I expected that it would not, but it's a place to start:
select m.messageid, p.name as "sender_name", p.name as "recipient_name"
from messages m, people p
where m.senderid = p.personid and m.recipientid = p.personid
The issue is that I don't know how in sql to specifically reference the sender and the recipient since they are part of the same join clause, if that makes sense.
thanks
try:
select m.messageid, pSender.name as "sender_name", pRecipient.name as "recipient_name"
from messages m
inner join people pSender on m.senderId = pSender.personId
inner join people pRecipient on m.recipientid = pRecipient.personId
For your join method (i think this should work... i'm not very familiar with comma joins)
select m.messageid, p.name as "sender_name", p.name as "recipient_name"
from messages m, people pSender, people pRecipient
where m.senderid = pSender.personid and m.recipientid = pRecipient.personid
You can join the same table into the query twice, just alias it differently, something aking to:
select m.messageid, s.name as "sender_name", r.name as "recipient_name"
from messages m
inner join people s on m.senderid = s.personid
inner join people r on m.recipientid = r.personid
Your query return only messages that is sent from a person to itself. Something like:
select m.messageid, p1.name as sender_name, p2.name as recipient_name
from messages m,
join people p1
on m.senderid = p1.personid
join people p2
on m.recipientid = p2.personid
That is you need one join for sender and one join for receiver
Related
Trying to figure out what I thought was a simple query-
I have the following tables with schemas as follows.
models(id: int, first_name: string, last_name: string)
painters(id: int, first_name: string, last_name:string)
portraits_painters(painter_id: int, portrait_id: int)
roles(model_id: int, portrait_id: int)
I am trying to satisfy this query: The first name, last name, and count
for painters who have been the model for their own painting- i.e. where the count column for a first and last name is the number of self portraits the painter has done (both the painter and model). (Safe to assume equal first names and last names mean the same individual).
If a painter has no self portraits they should not even be included in the final output.
SELECT
models.first_name,
models.last_name,
COUNT(portraits_painters.portrait_id)
FROM models
RIGHT JOIN painters
ON models.first_name = painters.first_name
AND models.last_name = painters.last_name
RIGHT JOIN portraits_painters
ON portraits_painters.painter_id = painters.id
RIGHT JOIN roles
ON roles.portrait_id = portraits_painters.portrait_id
GROUP BY portraits_painters.portrait_id;
I essentially tried to narrow the table down to rows where names matched, followed by instances where the painter ids matched and the portrait id's matched, but evidently there's something incorrect in how I am joining tables.
I'm also getting errors in regards to the GROUP BY portion, so not sure if there's a better way to approach it? Perhaps aliasing?
You can get the names of the models and painters using:
select m.first_name, m.last_name, p.first_name, p.last_name
from roles r join
portraits_painters pp
on pp.portrait_id = r.portrait_id join
painters p
on p.id = pp.painter_id join
models m
on m.id = r.model_id;
The rest is just a where and group by:
select p.first_name, p.last_name, count(*)
from roles r join
portraits_painters pp
on pp.portrait_id = r.portrait_id join
painters p
on p.id = pp.painter_id join
models m
on m.id = r.model_id
where m.first_name = p.first_name and m.last_name = p.last_name
group by p.first_name, p.last_name;
I am not sure what thinking leads to outer joins or exists clauses.
Get painter infos for all portraits:
SELECT p.first_name, p.last_name, pp.portrait_id
FROM portraits_painters AS pp
JOIN painters AS p
ON pp.painter_id = p.id
Get model infos for all portraits:
SELECT m.first_name, m.last_name, pp.portrait_id
FROM roles AS r
JOIN models AS m ON m.id = r.model_id
JOIN portraits_painters AS pp ON pp.portrait_id = r.portrait_id
Combine these two tables on the same first_name and last_name. Now you get both painter infos and model infos for every portrait. Just group the records by first_name and last_name, and COUNT for each group, you get what you want.
So, the final query would be:
SELECT a.first_name, a.last_name, COUNT(a.portrait_id)
FROM
(
SELECT p.first_name, p.last_name, pp.portrait_id
FROM portraits_painters AS pp
JOIN painters AS p
ON pp.painter_id = p.id
) AS a
JOIN
(
SELECT m.first_name, m.last_name, pp.portrait_id
FROM roles AS r
JOIN models AS m ON m.id = r.model_id
JOIN portraits_painters AS pp ON pp.portrait_id = r.portrait_id
) AS b
ON a.first_name = b.first_name AND a.last_name = b.last_name
GROUP BY a.first_name, a.last_name;
Just getting confused on basic stuff -
could someone explain me this -
select s.name from students s
inner join friends f on f.id = s.id
inner join packages p on p.id = s.id
where p.salary < (select pp.salary from packages pp where pp.id = f.friend_id)
order by (select pp.salary from packages pp where pp.id = f.friend_id) ASC;
the salary comparison part - i.e select pp.salary from packages pp where pp.id = f.friend_id should not yield the same salary result? - so how can we compare.
for references, use the below sample tables
table 1- students
columns - id, name
table 2 - friends (here each id is linked with one friend_id (his best friend))
columns - id , friend_id
table3 - packages
columns - id , salary
Trying to find out the name of the friend whose best friend's salary is more than his salary.
I am confused at understanding this solution.
That where subquery part is wrong cause the subquery will return multiple record and which can't be used with < operator since it's accepts scalar value. Rather change that to a JOIN as well like
JOIN packages pp ON pp.id = f.friend_id
AND p.salary < pp.salary
Change your query to be
select s.name from students s
inner join friends f on f.id = s.id
inner join packages p on p.id = s.id
JOIN packages pp ON pp.id = f.friend_id
AND p.salary < pp.salary
order by pp.salary;
I have the following query for a basic messaging system. It shows the messages that you've sent. However, it is showing the first_name and second_name for the account referenced by sender_id. Instead I want it to output the name columns referenced by receiver_id
ie) SELECT first_name, second_name WHERE accounts.account_id = messages.receiver_id
Do I need to write a seperate query for this or can I make this one output it in a single query? I've been thinking quite hard about this problem!
SELECT first_name, second_name, message_id, title, body, seen, urgent, type, messages.timestamp
FROM messages
INNER JOIN accounts
ON messages.sender_id=accounts.account_id
WHERE sender_id = ?
You can do this with two joins:
SELECT s.first_name as sender_first, s.second_name as sender_last,
r.first_name as rec_first, r.second_name as rec_last,
m.message_id, m.title, m.body, m.seen, m.urgent, m.type, m.timestamp
FROM messages m inner join
accounts s
ON m.sender_id = s.account_id inner join
accounts r
on m.receiver_id = r.account_id
WHERE m.sender_id = ?
I have three tables
post
id | statement | date
features
id | feature
post_feature (many to many table between Post and Feature)
post_id | feature_id
I want to fire a query that will give me count of different distinct features and its respective features for the posts that are in given date period. I have just started learning SQL and I am not able to crack this one.
I tried the following one but not getting correct results.
SELECT f.feature, count(f.feature)
FROM post_feature l
JOIN features f ON (l.featureid = f.id AND l.featureid IN (
select post.id from post where post.date > 'some_date'))
GROUP BY f.feature
You can try like this:
SELECT f.feature, count(f.feature)
FROM post_feature l
JOIN features f ON l.featureid = f.id
JOIN post p ON l.post_id =p.id
WHERE p.date > 'some_date'
GROUP BY f.feature
select f.feature, count(*)
from post_feature l inner join features f on l.feature_id = f.id
inner join post p on l.post_id = p.id
where p.date > 'some_date'
group by f.feature
Your SQL is quite creative. However, your join in the IN clause is on the wrong columns. It should be on postid to postid.
Although that fixes the query, here is a better way to write it:
SELECT f.feature, count(f.feature)
FROM post p join
post_feature pf
on p.id = pf.postid join
feature f
on pf.featureid = f.id
where post.date > 'some_date'
GROUP BY f.feature
This joins all the tables, and then summarizes by the information you want to know.
Try
SELECT f.feature, count(DISTINCT f.feature)
FROM post_feature l
JOIN features f ON (l.featureid = f.id AND l.featureid IN (
select post.id from post where post.date > 'some_date'))
GROUP BY f.feature
ok, here we go...
I have 3 tables: posts, comments and members, i need to get title from posts, msg from comments and username from members.
all tables has an identical ID to associate(?)
for example: i want to get these data from certain ID...
sorry for my bad english, isn't my language, and my very basic skill on MySQL (started today).
Edit:
this is my schema:
posts: |ID|title|
----------------
|1 |post title| (example data)
comments: |USERID|UID|msg| (UID is same as posts.ID)
-----------------
|5 |1 |message| (example data)
members: |USERID|username|
-----------------
|5 |myusername| (example data)
when i make a query to ID 80 (eg.) will return the title, the messages associated to that post (UID) and the username associated to that comment.
for eg. if the post 80 have 5 comments shows, title of post and username of comment.
i think this is more clear. (no?)
Maybe something like this:
SELECT P.Title, C.Message, M.Username
FROM Posts P
INNER JOIN Comments C ON P.PostID = C.PostID
INNER JOIN Memmbers M ON C.MemberID = M.MemberID
WHERE P.PostID = 123
Here it is with your schema (I think mine is better that's why I left it) :)
SELECT P.title, C.msg, M.username
FROM posts P
INNER JOIN comments C ON P.ID = C.UID
INNER JOIN memmbers M ON C.USERID = M.USERID
WHERE P.ID = 80
The post title will be repeated in this case, but I believe this is what you are asking for.
Without seeing your schema I can only guess but I think it might look something like this:
SELECT p.title, c.msg, m.username
FROM Posts p
INNER JOIN Comments c ON (p.AssociateID = c.AssociateID)
INNER JOIN Members m ON (m.AssociateID = p.AssociateID)
WHERE p.AssociateID = 123
If your schema is different, adjust the SQL above to fit your table structure.
First of all your tables structure (singular table names) should look like something like this:
post:
id
title
member_id
comment:
id
msg
post_id
member_id
member:
id
username
SELECT p.title, c.msg, m.username
FROM comment c
INNER JOIN post p ON p.id = c.post_id
INNER JOIN member m ON m.id = p.member_id
WHERE m.id = YOURUSERIDGOESHERE
You can also do something like:
SELECT P.Title, C.Message, M.Username
FROM Posts P, Comments C, Members M
WHERE P.ID = C.UID
AND C.USERID = M.USERID
AND P.PostID = 80
This will produce the same results as the JOIN several others suggested, but some people feel that the WHERE shows the relationships more clearly. This is just a matter of personal preference.