Tables
CREATE TABLE Users (user_id INTEGER PRIMARY KEY,
name VARCHAR(100) NOT NULL);
CREATE TABLE Ratings (user_id INTEGER NOT NULL,
rating INTEGER NOT NULL,
movie_name varchar(100) NOT NULL,
PRIMARY KEY(user_id, movie_name),
FOREIGN KEY (user_id) REFERENCES Users(user_id));
CREATE TABLE Similarity (user1_id INTEGER NOT NULL,
user2_id INTEGER NOT NULL,
similarity FLOAT,
PRIMARY KEY (user1_id, user2_id),
FOREIGN KEY (user1_id) REFERENCES Users(user_id),
FOREIGN KEY (user2_id) REFERENCES Users(user_id));
Query: Find all distinct user pairs with a Similarityi,j >= 0.7 whose watch list overlaps in at least 12 movies. The result should contain three columns: the user id of the first user and the user id of the second user, and the number of movies they have watched.
My Query: Returns null
SELECT DISTINCT U.user_id, U2.user_id
FROM Users U, Users U2, Ratings R, Similarity S
WHERE U.user_id != U2.user_id AND
R.user_id = U.user_id AND
R.user_id = U2.user_id AND
S.similarity >= 0.7;
I realized U.user_id != U2.user_id AND R.user_id = U.user_id AND R.user_id = U2.user_id makes the table return null. But how do I get distinct user_id pairings?
You need to join the tables
e.g.
FROM User U
JOIN Ratings R ON U.user_id = R.User_id
JOIN Similarity S ON S.user2_id = U.user_id
I would join them first and then use your where clause
Related
I try to return how many friends a user have through GROUP_CONCAT But i only get Lance and not also Bob and it seems if i remove the WHERE condition. It works fine, but i would like to keep it. Since i want get all rows which are connected to member
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);
INSERT INTO users (name)
VALUES ("Gregor"),
("Liza"),
("Matt"),
("Tim"),
("Lance"),
("Bob");
CREATE TABLE committee(
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
friend_id INT,
member_id INT,
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`member_id`) REFERENCES `users` (`id`)
);
INSERT INTO committee (user_id, friend_id, member_id)
VALUES (3, 5, 1),
(4, 5, 1),
(3, 6, 2),
(4, 6, 2);
Here is the query:
SELECT u.name,
GROUP_CONCAT(f.name) AS friends
FROM committee c
INNER JOIN users u ON (u.id = c.user_id)
INNER JOIN users AS f ON (f.id = c.friend_id)
WHERE (c.member_id = 1)
GROUP BY u.id;
What i get now:
name friends
Matt Lance
Tim Lance
What i expect:
name friends
Matt Lance,Bob
Tim Lance,Bob
You need another join with committee to find all the other committees that Matt and Tim are on, so you can find their friends from those committees.
SELECT u.name,
GROUP_CONCAT(f.name) AS friends
FROM committee c
INNER JOIN users u ON (u.id = c.user_id)
INNER JOIN committee c2 ON c2.user_id = c.user_id
INNER JOIN users AS f ON (f.id = c2.friend_id)
WHERE (c.member_id = 1)
GROUP BY u.id;
DEMO
I would like to fetch all users.myKey from the table committee if the id is in the table.
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
myKey VARCHAR(100)
);
INSERT INTO users (name, myKey)
VALUES ("Gregor", "kx4ht"),
("Liza", "1lPxk"),
("Matt", "mP3fd"),
("Bob", "zStr5");
CREATE TABLE committee(
user_id INT,
friend_id INT,
member_id INT,
PRIMARY KEY (`user_id`, `friend_id`, `member_id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`member_id`) REFERENCES `users` (`id`)
);
INSERT INTO committee (user_id, friend_id, member_id)
VALUES (4, 1, 3),
(1, 2, 3);
What i got now:
SELECT u.myKey FROM users u INNER JOIN committee c ON (c.user_id = u.id || c.friend_id = u.id || c.member_id = u.id) WHERE u.id = 2 GROUP BY u.id;
Result now:
I get only my own myKey user_id2
What i expect:
I want only get the myKeys for the others inside committee. E.g if i user 2 want get the myKeys from table committee where i can find my user id 2
In this case it should return the myKey for user1 and user3
As far as I understand your problem, you want to find a specific id in the "committee" table, find the id's that are next to the specified id and then find those neighboring ids in the "users" table and show their keys.
This is what I have come up with:
SELECT u.id, u.myKey
FROM users u
LEFT JOIN (SELECT IF (tmp.user_id = 2, NULL, tmp.user_id) AS user_id,
IF(tmp.friend_id = 2, NULL, tmp.friend_id) AS friend_id,
IF(tmp.member_id = 2, NULL, tmp.member_id) AS member_id
FROM (SELECT *
FROM committee
WHERE user_id = 2 OR friend_id = 2 OR member_id = 2) AS tmp) AS id_table
ON u.id = id_table.user_id OR u.id = id_table.friend_id OR u.id = id_table.member_id
WHERE user_id IS NOT NULL OR friend_id IS NOT NULL OR member_id IS NOT NULL;
Note that I am searching for the user with the id 2, as you specified.
The result of this query, as you said you would have expected it:
id | myKey
1 kx4ht
3 mP3fd
I have three tables.
CREATE TABLE IF NOT EXISTS users (
userID int AUTO_INCREMENT,
username text NOT NULL,
password text NOT NULL,
PRIMARY KEY (userID)
);
CREATE TABLE IF NOT EXISTS schedule (
actID int AUTO_INCREMENT,
actName text NOT NULL,
actDay text NOT NULL,
actStart text NOT NULL,
actStop text NOT NULL,
PRIMARY KEY (actID)
);
CREATE TABLE IF NOT EXISTS connection (
userID int,
actID int,
FOREIGN KEY (userID) REFERENCES users(userID),
FOREIGN KEY (actID) REFERENCES schedule(actID)
);
I am using a third table (connection) to connect the first two tables (users and schedule) with FOREIGN KEY. How can I get all activities from schedule for a specific user?
If you want to search by user's name you must join all 3 tables:
select u.*, s.*
from users u
inner join connection c on c.userID = u.userID
inner join schedule s on s.actID = c.actID
where u.username = ?
If you want to search by user's id you must join only 2 tables:
select c.userID, s.*
from connection c inner join schedule s
on s.actID = c.actID
where c.userID = ?
If a user does not have any activities but you want in the results 1 row, with no activity then use left joins:
select u.*, s.*
from users u
left join connection c on c.userID = u.userID
left join schedule s on s.actID = c.actID
where u.username = ?
I tried to rename the table using join, but I'm running into the Unknown column 'R.movie_name' in 'on clause'. I referenced this question to correct, but I'm still get the same error.
What am I doing wrong?
My SQL query
SELECT R.movie_name, AVG(S.similarity*R.rating)
FROM Ratings AS R, Similarity S
INNER JOIN (
SELECT DISTINCT R.movie_name
FROM Ratings R, Users U
WHERE U.name = 'Adam Brody' AND U.user_id != R.user_id
) AS MoviesAdamDidntWatch ON R.movie_name = MoviesAdamDidntWatch.movie_name
GROUP BY R.movie_name;
My Tables
CREATE TABLE Users (user_id INTEGER PRIMARY KEY,
name VARCHAR(100) NOT NULL);
CREATE TABLE Ratings (user_id INTEGER NOT NULL,
rating INTEGER NOT NULL,
movie_name varchar(100) NOT NULL,
PRIMARY KEY(user_id, movie_name),
FOREIGN KEY (user_id) REFERENCES Users(user_id));
CREATE TABLE Similarity (user1_id INTEGER NOT NULL,
user2_id INTEGER NOT NULL,
similarity FLOAT,
PRIMARY KEY (user1_id, user2_id),
FOREIGN KEY (user1_id) REFERENCES Users(user_id),
FOREIGN KEY (user2_id) REFERENCES Users(user_id));
You have used R twice as Alias in your query . You can fix it by replacing outer R with some other alias. like -
SELECT Rtg.movie_name, AVG(S.similarity*Rtg.rating)
FROM Ratings AS Rtg, Similarity S
INNER JOIN (
SELECT DISTINCT R.movie_name
FROM Ratings R, Users U
WHERE U.name = 'Adam Brody' AND U.user_id != R.user_id
) AS MoviesAdamDidntWatch ON Rtg.movie_name = MoviesAdamDidntWatch.movie_name
GROUP BY Rtg.movie_name;
But your query is not optimised, Consider optimising it by removing redundant inner query and cross products.I may help you with it if you post your table structure.
Given the following two tables:
users (user_id, username, location,
email)
votes (user_id, value, date, ip)
How can I perform a MySQL query to return all the users with total number of votes and sum of votes for each user?
Thank you.
select u.user_id,
(select count(user_id)
from votes v
where v.user_id = u.user_id) as num_votes,
(select sum(value)
from votes v
where v.user_id = u.user_id) as sum_votes
from users u
# if you want: order by ...
EDIT: The subselects are not the most elegant solution, and not really necessary. So here's an outer join version:
select u.user_id, count(v.user_id) as num_votes, sum(v.value) as sum_votes
from users u
left outer join votes v
on u.user_id = v.user_id
group by u.user_id
This works for me:
create table user
(
id int not null auto_increment,
name varchar(80) not null,
location varchar(80) default '',
email varchar(80) default '',
primary key(id)
);
create table vote
(
id int not null auto_increment,
count int not null,
election_date date,
user_id int,
primary key(id),
foreign key(user_id) references user(id)
);
select
user.name, user.email, sum(vote.count)
from user
left join
vote
on user.id = vote.user_id
group by (user_id)