I'm trying to write a friend system that works like this:
User A sends friend request to user B.
User B accepts friend request from user A.
Users A and B are now friends.
Here is my database structure:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(16) NOT NULL,
`password` char(32) NOT NULL,
`email` varchar(80) NOT NULL,
`dname` varchar(24) NOT NULL,
`profile_img` varchar(255) NOT NULL DEFAULT '/images/default_user.png',
`created` int(11) NOT NULL,
`updated` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
CREATE TABLE IF NOT EXISTS `friend_requests` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_a` int(11) NOT NULL DEFAULT '0',
`user_b` int(11) NOT NULL DEFAULT '0',
`viewed` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
CREATE TABLE IF NOT EXISTS `friends` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_a` int(11) NOT NULL DEFAULT '0',
`user_b` int(11) NOT NULL DEFAULT '0',
`friend_type` int(3) NOT NULL DEFAULT '1',
`friends_since` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
I can list a users friends with "SELECT * FROM friends WHERE user_a = $userid OR user_b = $userID", but how can I get data such as username or profile_img from the users table?
I think you have overthunk (!) your problem a bit.
You could have just a Usertable and a Friendshiptable. Your Friendship-table could contain UserID int, FriendID int, Created_at datetime, Confirmed_at datetime.
select * from User
left outer join Friendship on User.ID = Friendship.UserID
left outer join User as Friend on Friendship.FriendID = Friend.ID
where User.ID = <some users ID>
Edit: I may have overthunk it myself the first time around ;)
select * from Friendship
inner join User on Friendship.FriendID = User.ID
where Friendship.UserID = <some users ID>
This would get a users friends...
(MSSQL syntax)
Oh, i forgot. When Confirmed_at is null the Friendship-request is not yet confirmed.
SELECT DISTINCT
a.username,
a.profile_img
FROM
users a
WHERE
a.id in (SELECT user_a FROM friends WHERE user_a = $userid OR user_b = $userID)
and a.id <> $userid
UNION
SELECT
b.username,
b.profile_img
FROM
users b
WHERE
b.id in (SELECT user_b FROM friends WHERE user_a = $userid OR user_b = $userID)
and b.id <> $userid
You'll need to use joins to join the table friends to users.
Eg:
SELECT * FROM friends as f INNER JOIN users AS u ON u.id = f.user_a WHERE user_a = $userid
Related
I have a photo contest app where users can vote. I would like to select all of the contests where the logged in user has not voted yet.
So I have two tables.
The "contest" table :
CREATE TABLE `contest` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`desc` text NOT NULL,
`created_date` datetime NOT NULL,
`started_date` datetime NOT NULL,
`nb_user_min` int(11) NOT NULL,
`nb_photo_max` int(11) NOT NULL,
`nb_photo_per_user` int(11) NOT NULL,
`duration` int(11) DEFAULT NULL,
`status` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
The "contest_vote" table :
CREATE TABLE `contest_vote` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`pic_id` int(11) DEFAULT NULL,
`contest_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`date` datetime DEFAULT NULL,
`ip` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
So to be clear, I want to get the number (or the list) of contests where the user has not voted yet. So I have tried with a LEFT JOIN but it doesn't return the good set of result. Here it the query I have until now :
SELECT DISTINCT c.id, c.title, cv.user_id
FROM contest c
LEFT JOIN contest_vote cv
ON cv.contest_id = c.id AND cv.user_id != ?
GROUP BY contest_id
("?" represents the user_id parameter).
Can you help me to solve this?
This is pretty simple do with a subquery. Just grab all contest without where user is voted like this:
SELECT DISTINCT c.id, c.title
FROM contest c
WHERE c.id NOT IN (SELECT DISTINCT cv.contest_id FROM contest_vote cv WHERE cv.user_id = ?)
Try this one :
SELECT DISTINCT c.id, c.title, cv.user_id
FROM contest c
LEFT JOIN contest_vote cv ON cv.contest_id = c.id AND cv.user_id != ? WHERE c.user_id = ?
GROUP BY contest_id
I have three tables
User > id, username, name, age, sex, location
User Post > id, user_id, description, image, postime, location
Follow > id, user_id, follow_id, status
In User table I will be having all the user information.
In User Post table I will be having all the post related information.
I want to display my own post and also post of the users I am following
The query I had written for this situation is
SELECT
u.username,
u.name,
u.profile_pic,
up.*
FROM user u, user_post up
WHERE (up.user_id = $user_id OR up.user_id IN
(SELECT user_id
FROM follow WHERE follow_id=$user_id)), $user_id)
AND description='' group by id order by postime desc
I feel the query is wrong, can anyone help me
CREATE TABLE IF NOT EXISTS `user` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`username` varchar(30) NOT NULL,
`password` varchar(1000) NOT NULL,
`email` varchar(100) NOT NULL,
`age` varchar(100) NOT NULL,
`gender` varchar(100) NOT NULL,
`city` varchar(100) NOT NULL,
`state` varchar(100) NOT NULL,
`country` varchar(100) NOT NULL,
`profile_pic` varchar(100) NOT NULL,
`deviceToken` char(64) DEFAULT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE IF NOT EXISTS `user_post` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`description` varchar(100) NOT NULL,
`image` varchar(100) NOT NULL,
`location` varchar(100) NOT NULL,
`postime` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` int(20) NOT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE IF NOT EXISTS `follow` (
`id` int(100) NOT NULL AUTO_INCREMENT,
`user_id` int(100) NOT NULL,
`follow_id` int(100) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`status` varchar(20) NOT NULL DEFAULT 'Pending',
PRIMARY KEY (`id`)
)
This is the same answer I posted yesterday:
SELECT u.username,u.name,u.profile_pic, up.*
FROM user u JOIN user_post up
ON up.user_id = u.id
WHERE
(up.user_id = $user_id
OR
up.user_id IN (
SELECT user_id
FROM follow
WHERE follow_id=$user_id
)
)
AND description=''
ORDER BY postime DESC
As you didn't tell about the relations between user and follower it might enough to switch follow_idand user_id:
SELECT u.username,u.name,u.profile_pic, up.*
FROM user u JOIN user_post up
ON up.user_id = u.id
WHERE
(up.user_id = $user_id
OR
up.user_id IN (
SELECT follow_id
FROM follow
WHERE user_id=$user_id
)
)
AND description=''
ORDER BY postime DESC
I'm making a social plugin for my website, and I have a friends table that holds all accepted friend requests, and I need to display all posts from the users friend AND the users posts in order of the date, so I've tried this sql query:
SELECT DISTINCT `social_posts`.*, `social_friends`.*, `users`.*
FROM `social_posts`
JOIN `social_friends`
ON `fUID` = '1' AND `friend` = `pUID` OR `pUID` = '1'
JOIN `users`
ON `friend` = `uid`
ORDER BY `date` DESC
Structure
CREATE TABLE `social_friends` (
`fID` int(11) NOT NULL AUTO_INCREMENT,
`fUID` int(11) NOT NULL,
`friend` int(11) NOT NULL,
PRIMARY KEY (`fID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `social_posts` (
`pid` int(11) NOT NULL AUTO_INCREMENT,
`pUID` int(11) NOT NULL,
`body` text NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
fUID is the users (viewing) user ID, and friend is the users friend, and pUID is the user ID of the user who made the post.
But this shows two of each post, even with SELECT DISTINCT, and I'm out of ideas on how to figure this out.
1 - Can you give as more info (the fields) of the tables?
What is fUID and pUID
2 - Try and change
ON `fUID` = '1' AND `friend` = `pUID` OR `pUID` = '1'
to ON friend = pUID and put fUID = 1 OR pUID = 1 in the WHERE clause
I need a little help for one sql query;
here is my basic user database table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) NOT NULL,
`pass` varchar(255) NOT NULL,
`fname` varchar(50) NOT NULL,
`lname` varchar(40) NOT NULL,
`network` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=27 ;
and here is my basic topics database table
CREATE TABLE IF NOT EXISTS `topics` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` varchar(100) NOT NULL,
`title` varchar(255) NOT NULL,
`body` text,
`tags` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
What I'm trying to do is;
i.e. list all topics from users who joined "harvard" network
You just need a simple JOIN. Join the tables on the userID (of those who are in "harvard").
SELECT title,body
FROM topics, users
WHERE userid = users.id
AND network = 'harvard'
Or using the JOIN keyword:
SELECT title,body
FROM topics
JOIN users ON userid = users.id
WHERE network = 'harvard'
This should do the trick, I think:
SELECT
title
FROM
topics t
INNER JOIN
users u ON t.userid=u.id
WHERE
network='Harvard'
SELECT t.title
FROM users u
INNER JOIN topics t ON u.id = t.userid
WHERE u.network = 'harvard'
GROUP BY u.id
I have a users table.
I have a certifications table.
Each user can have multiple certifications. Certifications has a user_id foreign key.
How may I select a user as well as all of their certifications in one query?
How may I select users that have certifications?
users table:
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL auto_increment,
`username` varchar(24) default NULL,
`displayname` varchar(24) default NULL,
`email` varchar(64) default NULL,
`password` text,
`signup_date` int(11) default NULL,
`signup_ip` varchar(15) default NULL,
`hash` text,
`verified` tinyint(1) default '0',
`last_login` int(11) default NULL,
`logins` int(11) default NULL,
`status` text,
`recovery_hash` text,
`recovery_initiated` int(11) default NULL,
`last_updated` int(11) default NULL,
`signup_method` text,
`signup_question` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
certifications table:
CREATE TABLE `certifications` (
`id` int(11) unsigned NOT NULL auto_increment,
`user_id` int(11) unsigned NOT NULL,
`number` varchar(128) default NULL,
`board` varchar(128) default NULL,
`company` varchar(128) default NULL,
`website` varchar(128) default NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `certifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Thank you for reading.
How may I select a user as well as all of their certifications in one query?
SELECT *
FROM certifivations C
LEFT JOIN users U
ON C.user_id = U.id
WHERE U.id=USERID
How may I select users that have certifications?
SELECT *
FROM certifivations C
JOIN users U
ON C.user_id = U.id
GROUP BY U.id
Get all the certifications of user with id of 1 by using a join.
SELECT b.id as certification_id
FROM users AS a
LEFT JOIN certifications AS b
ON a.id = b.user_id
WHERE a.id = 1;
Get all the users that have certifications using an inner join. All users without certs will drop out.
SELECT a.id as users_with_certifications
FROM users as a
JOIN certifications AS b
ON a.id = b.user_id;