I will try simplify my example. I've got a table called friendship with two relations to user (lets call them user1 and user2). I would like to retrieve an alphabetical list of my friends. I can appear in the user1 or in the user2. The only way I can know is by using unions:
SELECT f.*
FROM
(SELECT "user1"."name" AS "name"
FROM "friendship" AS "friendship" LEFT JOIN "user" AS "user1"
ON "friendship"."user1_id" = "requestedUser"."id"
AND "user1"."id" != 'me'
WHERE ("friendship"."user2_id" = 'me')
UNION
SELECT "user2"."name" AS "name"
FROM "friendship" AS "friendship"
LEFT JOIN "user" AS "user2"
ON "friendship"."user2_id" = "user2"."id"
AND "user2"."id" != 'me'
WHERE ("friendship"."user1_id" = 'me')
) AS f
ORDER BY "name"
LIMIT ?;
Is there any easier way? Or maybe there is possibility to do it in single SELECT? Do you know how do it in sequelize?
in Sequelize you should be able to do user.getFriends() to get all of a users friends. If you aliased the associations to something like outbound and inbound it would be user.getInbound() and user.getOutbound().
Sequelize automatically creates and names methods on instances that allow you to get associated models.
Related
Suppose I have a table called UserFollows, where I keep Follow relationships ;
UserId
FollowedId
Then I have a general Users table and it is like ;
Id
Username
I use a query like the following when I want to get all followers of a user with ID 100 ;
SELECT*FROM UserFollows WHERE FollowedId = 100;
And suppose that I also want to query the following case ;
I want to search among the followers of a particular user, with a specific Username.
So, It should be like GET ME ALL OF THE USERS THAT HAS THE WORD 'hey' IN THEIR USERNAMES AMONG THOSE FOLLOWING ME
If I had Username in my UserFollows table , I'd easily write it like ;
SELECT*FROM UserFollows WHERE FollowedId = 100 AND Username LIKE '%a';
But I don't keep their Usernames in UserFollows
You need to include the Users table in the query.
SELECT uf.*
FROM UserFollows uf
inner join Users u on u.Id = uf.UserId
WHERE uf.FollowedId = 100
AND u.Username LIKE '%a';
or, more clearly
SELECT uf.*
FROM UserFollows uf
inner join Users follower on follower.Id = uf.UserId
inner join Users followed on followed.Id = uf.FollowedId
WHERE followed.UserName = 'ME'
AND follower.Username LIKE '%a';
Although "followed" may be a keyword, so you would need different aliases or you would need to handle the names appropriately.
I have two tables, Users and Relationships tables. Users table has following columns:
id, name,password,username,email,avatar,followersCount,followingCount,tweetCount.
And the Relationships table has the following columns:
id, followingId, followerId
How should I go about creating a SQL query to extract a user with a specific Id and find id's from Relationships that user is following? So in other words find people that user follows
I've come this far so long
SELECT *
FROM public."Users" JOIN
public."Relationships"
ON (public."Users".id = public."Relationships".id)
If I understand correctly, you want:
SELECT u.*
FROM public."Relationships" r JOIN
public."Users" u
ON u.id = r.followerId
WHERE r.followingId = ?;
? is a parameter placeholder for the user you care about. This returns all the followers of that user.
Do you mean this query
SELECT public."Users".*
FROM public."Users"
JOIN public."Relationships"
ON public."Users".id = public."Relationships".followingId
AND public."Relationships".followerId = a user ID
I am not really clear about followerId and followingId mean but you can change them in the query if it is not what you want.
This is task table:
This is user table:
I want to select user tasks.
I would give from backend ("given_to_user) id.
But The thing is I want that SELECTED data would have usernames instead of Id which is (created_by_user and given_to_user).
SELECTED table would look like this.
Example:
How to achieve what I want?
Or maybe I designed poorly my tables that It is difficult to select data I need? :)
task table has to id values that are foreign keys to user table.
I tried many thinks but couldn't get desired result.
You did not design poorly the tables.
In fact this is common practice to store the ids that reference columns in other tables. You just need to learn to implement joins:
SELECT
task.id, task.title, task.information, user.usename AS created_by, user2.usename AS given_to
FROM
(task INNER JOIN user ON task.created_by_user = user.id)
INNER JOIN user AS user2 ON task.created_by_user = user2.id;
Do you just want two joins?
select t.*, uc.username as created_by_username,
ug.username as given_to_username
from task t left join
users uc
on t.created_by_user = uc.id left join
users ug
on t.given_to_user = ug.id;
This uses left join in case one of the user ids is missing.
I know the title isn't so describing but it's really hard to find something generic to describe my situation. If someone wants to edit, feel free...
So, I have a postgres database, with a users table. I would like to store the users followed by one user, and I really don't see how I could do this. I would like to do like SELECT followed_users FROM users WHERE username='username' and this would return me every usernames, or id, or whatever of each followed users. But I don't see any clean way to do this.
Maybe an example would be more describing: user1 is following user2 and user3.
How to store who user1 is following?
EDIT: I don't know how many users the user will follow.
Thank you for your help.
Expanding on my comment above, since it got wordy:
Create a new table called something like user_follows with columns like
user_id1 | user_id2
or
follower_id | follows_id
Then you can query:
SELECT t1.username as follower_username, t3.username as following_usernae
FROM users t1
INNER JOIN user_follows t2 ON t1.user_id = t2.follower_id
INNER JOIN users t3 ON t2.following_id = t3.user_id
WHERE t1.user_id = <your user>
In the end, think of your tables as "Objects". Then when you are presented with a problem like "How do I add users that are following other users" you can determine if this relationship is a new object, or an attribute of an existing object. Since a user might follow more than one other user than the relationship is not a good attribute for "Users", so it gets its own table user_follows.
Since user_follows is just one type of relationship that two users may have to one another, it might make sense to increase the scope of that object to relationships and store the relationship type as an attribute of the table:
user_id1 | user_id2 | relationship_type
where relationships.relationship_type might have values like follows, student of, sister of etc...
So the new query would be something like:
SELECT t1.username as follower_username, t3.username as following_username
FROM users t1
INNER JOIN relationships t2 ON t1.user_id = t2.user_id1
INNER JOIN users t3 ON t2.user_id2 = t3.user_id
WHERE t1.user_id = <your user> AND t2.relationship_type = 'Follows';
I'd add another table, let's call it following for argument's sake, which saves pairs of users and users they are following:
CREATE TABLE following (
user_id INT NOT NULL REFERENCES users(id),
following_id INT NOT NULL REFERENCES users(id),
PRIMARY KEY (user_id, following_id)
)
Then you could query all the user's a specific user is following by joining with the users table (twice). E.g., to get the names of all the users that I (username "mureinik") am following:
SELECT fu.username
FROM following f
JOIN users u ON f.user_id = u.id
JOIN users fu ON f.user_id = fu.id
WHERE u.username = 'mureinik'
Sorry if that title is a bit convoluted... I'm spoiled by an ORM usually and my raw SQL skills are really poor, apparently.
I'm writing an application that links to a vBulletin forum. Users authenticate with their forum username, and the query for that is simple (selecting by username from the users table). The next half of it is more complex. There's also a subscriptions table that has a timestamp in it, but the primary key for these is a user id, not a username.
This is what I've worked out so far:
SELECT
forum.user.userid,
forum.user.usergroupid,
forum.user.password,
forum.user.salt,
forum.user.pmunread,
forum.subscriptionlog.expirydate
FROM
forum.user
JOIN forum.subscriptionlog
WHERE
forum.user.username LIKE 'SomeUSER'
Unfortunately this returns the entirety of the subscriptionlog table, which makes sense because there's no username field in it. Is it possible to grab the subscriptionlog row using the userid I get from forum.user.userid, or does this need to be split into two queries?
Thanks!
The issue is that you are blindly joining the two tables. You need to specify what column they are related by.
I think you want something like:
SELECT * FROM user u
INNER JOIN subscriptionlog sl ON u.id = sl.userid
WHERE u.username LIKE 'SomeUSER'
select * from user u JOIN subscriptions s ON u.id = s.id where u.username = 'someuser'
The bit in bold is what you want to add, it combines the 2 tables into one that you return results from.
try this
SELECT
forum.user.userid,
forum.user.usergroupid,
forum.user.password,
forum.user.salt,
forum.user.pmunread,
forum.subscriptionlog.expirydate
FROM
forum.user
INNER JOIN forum.subscriptionlog
ON forum.subscriptionlog.userid = forum.user.userid
WHERE
forum.user.username LIKE 'SomeUSER'