(The example that follows is hypothetical, but illustrates the concept).
Using MySQL, say I have 2 tables:
userFromID userToId moreInfo
1 2 cat
1 3 dog
4 1 bear
3 4 fish
And...
userId someInfo addlInfo
1 m 32
2 f 33
3 m 25
4 f 28
And I want to query for a user id, and get back joined info from both tables for all users that share a relationship with user1.
assume that the first table has something like alter table thatFirstTable add unique index(userFromId, userToId) so there won't be any duplicates - each relationship between the two ids will be unique.
it doesn't matter who's the "from" or "to"
so the desired result would be something like this, if queried for relationships with user id: 1
userId moreInfo someInfo addlInfo
2 cat f 33
3 dog m 25
4 bear f 28
Thanks.
/EDIT this "works" but I suspect there's a better way?
SELECT * FROM users JOIN friends ON friends.userFrom = users.id OR friends.userTo = users.id WHERE users.id != 1 AND friends.userFrom = 1 OR friends.userTo = 1
/EDIT2 - I updated the sample output to better reflect the goal
try this query::
select tbl2.userid,tbl1.moreinfo,
tbl2.someinfo,tbl2.addinfo
from tbl1 join tbl2
on (tbl1.usertoid = tbl2.userid and tbl1.userfromid = 1)
You should just join the tables with the query below.
select u.userId, f.moreInfo, u.someInfo, u.addlInfo
from users AS u INNER JOIN friends AS f ON u.userId = f.UserToId
where f.userFrom = 1
Try this. Tested and 100% working
select a.userToID, a.moreInfo, b.someInfo, b.addInfo from tbl1 a
left outer join
tbl2 b on a.userToID = b.userId
where a.userFromID = 1;
Related
I have a social media like database where users can follow each other, and users can also have interests.
I would like to know how I can return the row(s) that list the users who are following each other and who have at least one interest in common.
I have written the query to display the users who follow each other, and what the user who is being followed is interested in. I need to isolate the pairs of users who follow each other and are interested in the same thing.
CODE SO FAR:
SELECT me.followed, me.following, me.interest FROM
(SELECT followed, following, interest
FROM follow JOIN interest
WHERE followed = interest.user_id
ORDER BY followed) AS me
INNER JOIN follow AS you ON me.following = you.followed
WHERE me.followed = you.following
[table] https://i.imgur.com/t68T4OI.png
A B C
2 1 2
2 1 6
2 1 9
1 2 1
1 2 7
1 2 8
7 15 1
7 15 7
15 7 2
15 7 7
(A = followed, B = following, C = user interest)
Sorry for the formatting, there seems to be no simple way to make tables.
My table so far shows that user 2 follows user 1, and user 1 follows user 2. Same for users 15 and 7. It also shows user 2 is interested in interest 2, interest 6, and interest 9.
I want to write some code that should just return user 7 and user 15, as they are the only users that follow each other and have a common interest (interest 7), but I'm not sure where to start.
I don't knwo if I've misunderstood, but can this query be answered by just the user_follow table?
SELECT * FROM
user_follow a
INNER JOIN
user_follow b
ON
a.followed_user_id = b.following_user_id AND
a.following_user_id = b.followed_user_id AND
a.interest_id = b.interest_id
You need another join to user_interest:
SELECT me.followed_user_id, me.following_user_id,
me.interest_id AS 'same interest id'
FROM user_follow AS me
JOIN user_follow AS you -- me and you follow each other
ON me.following_user_id = you.followed_user_id
AND me.followed_user_id = you.following_user_id
JOIN user_interest AS me_int -- my interest
ON me.following_user_id = me_int.user_id
JOIN user_interest AS you_int -- your interest
ON me.followed_user_id = you_int.user_id
AND me_int.interest_id = you_int.interest_id --must be the same
If I were writing this query, I would want a result set where pairs of users only appear once and there is a count of interests in common.
So:
select uf.followed_user_id, uf.following_user_id,
count(*) as interests_in_common
from user_follow uf join
user_interest uifed
on uifed.user_id = uf.followed_user_id join
user_interest uifing
on uifing.user_id = uf.followed_user_id and
uifing.interest_id = uifed.interest_id
where (uf.followed_user_id, uf.following_user_id) in
(select uf2.following_user_id, uf2.followed_user_id
from user_follow uf2
) and
uf.followed_user_id < uf.following_user_id
group by uf.followed_user_id, uf.following_user_id;
First, I realize there are other similar questions, I have read through many of them and I cannot figure this out.
I have three tables like so.
urilist
----------------
rowid | uri
1000 xyz
1001 abc
1002 cde
1003 fgh
wordlist
----------------
rowid | word
1 word1
2 word2
3 word3
4 word4
wordlocation2
----------------
uriid | wordid
1001 1
1001 2
1001 3
1001 4
Table a hold uris. Table b holds words. Table c is a lookup table where you can see every word associated with a uri or vice versa.
I need to return the words for a given uri. so for uri abc I need words word1,word2,word3,word4.
This was my latest attempt.
select word from wordlist join wordlocation2 on wordlist.rowid =
wordlocation2.wordid
left join urilist on wordlocation2.uriid = urilist.rowid
and urilist.uri = "a uri address";
This returned thousands of unrelated answers. I'm not really sure of the best way to do this. Any help would be much appreciated.
Let us look at your query result by selecting *. I have used 'a uri address' as given by you for demonstrating regarding LEFT JOIN
Query:
select * from wordlist join wordlocation2 on wordlist.rowid = wordlocation2.wordid left join urilist on wordlocation2.uriid = urilist.rowid and urilist.uri = "a uri address";
This will fetch the below result
As you have done wordlocation2 LEFT JOIN urilist, even if there is no matching row for urilist, a value will come in the result by making the urilist value as NULL (this is the meaning of left join). In your case, you should not get any value if there is no matching row. So, use JOIN instead of LEFT JOIN.
select * from wordlist join wordlocation2 on wordlist.rowid = wordlocation2.wordid join urilist on wordlocation2.uriid = urilist.rowid where urilist.uri = "abc";
I think the order of tables doesn't matter as everything is inner join here. I am always ready to correct myself if anyone gives some suggestion on this.
This should be your query:
select l.word from urilist u
join wordlocation2 w on w.uriid = u.rowid
join wordlist l on l.rowid = wordid
where u.uri = 'some_uri'
Use:
select u.uri, wl.word
from urilist u
join wordlocation2 wl2 on wl2.uriid = u.id
join wordlist wl on wl2.wordid = wl.rowid
I have 2 tables
TBL 1: property TBL 2: property_detail
--------------------- --------------------------------------
Id Name status property_id param value
--------------------- --------------------------------------
1 X 1 1 parking two-wheeler
2 Y 1 1 furnishing furnished
3 Z 0 2 parking car-parking
4 A 1 2 furnishing semi-furnished
5 B 1 3 furnishing furnished
6 C 0 4 parking car-parking
"property_id" column in "property_detail" is foreign key of "Id" column in "property"
I want search result for status=1 and (param="parking" and value="car-parking") and (param="furnishing" and value="furnished")
From above Example table, the result will be
Result
-------------
id name
-------------
2 Y
How to achieve this?
you can get your desired result set by using join twice with details table
select p.*
from property p
join property_detail d on (p.Id = d.property_id)
join property_detail d1 on (p.Id = d1.property_id)
where p.status=1
and d.param='parking' and d.value='car-parking'
and d1.param='furnishing' and d1.value='semi-furnished';
Another way you can also use below query using having clause and sum function
select p.*
from property p
join property_detail d on (p.Id = d.property_id)
where p.status=1
group by p.Id
having sum(param="parking" and value="car-parking")
and sum(param="furnishing" and value="semi-furnished")
DEMO
SELECT property.id, property.name
FROM property INNER JOIN property_detail
ON property.id = property_detail.property_id
WHERE
(`param`="parking" AND `value`="car-parking")
AND
(`param`="furnishing" AND `value`="furnished")
AND status = 1;
can you try this one? I'm not sure though.. but it'll give you an idea.
So I basicly have a database that looks like this:
card_types
id description price
1 Card1 1.00
2 Card2 2.00
3 Card3 3.00
card_occasions
id occasion
1 birthday
2 graduation
3 thank you
4 other
type_occasions
ID TypeID OccasionID
1 1 1
2 1 2
3 1 4
4 2 3
I am trying to do an inner join using WHERE card_type.ID = 1 resulting in a similar output but I have no idea where to begin.
Example output:
card_occasion.ID card_occasions.Name
1 birthday
2 graduation
4 other
Any help would be appreciated.
Thanks.
Since type_occasions already owns the typeid, you don't need to join the type table.
SELECT o.id, o.occassion
FROM card_occasions o
INNER JOIN type_occasions t ON t.occassionid = o.id
WHERE t.typeid = 1
You begin with the table where you want values. After Join the table you need to make the relation.
SELECT card_occasions.id, card_occasions.occasion
FROM card_occasion co
INNER JOIN type_occasions to ON (to.OccasionID = co.id)
^ the relation between two table
WHERE ct.ID = 1
SELECT A.id,A.occasion FROM card_occasions A JOIN type_occasions B ON B.OccasionID= A.id AND B.TypeID=1
And if you really want to link all three tables for reason we don't see here you may use this method. This starts linking from the type_occasion table to appropriate "basic data" tables.
Select
typeo.OccasionID, co.occasion as Name
From type_occasion typeo
JOIN card_type ct ON (typeo.TypeID=ct.id)
JOIN card_occasion co ON (typeo.OccasionID=co.id)
Where
typeo.TypeID=1
-- ct.id=1
I asked this last week over the weekend and it got buried in the archives before anyone could answer. So forgive me if you've already seen this.
I teach classes and want to be able to select those students who have taken one class, but not another class. I have two tables: lessons_slots which is the table for every class such as:
--------------------
-ID name slots-
-1 basics 10 -
-2 advanced 10 -
-3 basics 10 -
---------------------
The other table is class_roll, which holds enrollment info, such as:
--------------------
-sID classid firstname lastname-
-1 1 Jo Schmo
-2 1 Person Two
...
-13 2 Jo Schmo
---------------------
What I want to do, I select everyone who has not had the advanced class (for example). I've tried doing
SELECT *
FROM lessons_slots
LEFT JOIN class_roll
ON lessons_slots.ID = class_roll.classid
WHERE lessons_slots.name != 'advanced'
But that doesn't work...All it does is eliminate that row, without eliminating the user. I want Jo Schmo, for example, to not show up in the results. Any ideas?
Not pretty, but works.
SELECT c.*
FROM lessons_slots l
join class_roll c on l.id=c.classid
where concat(firstname,lastname) not in (select concat(firstname,lastname)
from lessons_slots l
join class_roll c on l.id=c.classid where name='advanced')
SELECT * FROM class_roll cl LEFT JOIN lessons_slots ls
ON cl.classid = ls.id AND ls.name != 'advanced'
So you actually want to delete rows? Well then:
DELETE FROM class_roll cl LEFT JOIN lessons_slots ls
ON cl.classid = ls.id AND ls.name != 'advanced'
You could try something to the effect of
SELECT FirstName, LastName FROM class_roll
WHERE NOT EXISTS
(SELECT * FROM class_roll, lesson_slots
WHERE class_roll.classid = lesson_slots.ID
AND lesson_slots.name = 'advanced')
You can then use the result as the basis of a DELETE query.