Connecting two tables using third table with foreign key in mySQL - mysql

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 = ?

Related

Trying to find 3 columns from 3 different tables

I have the following 3 tables:
CREATE TABLE Pins (
email varchar(100) NOT NULL,
boardID int NOT NULL,
));
CREATE TABLE Boarders (
email varchar(100) NOT NULL,
boardID int NOT NULL,
FOREIGN KEY (categoryName) REFERENCES Category (name));
CREATE TABLE User (
email varchar(100) NOT NULL,
name varchar(50),
PRIMARY KEY (email));
I am wanting to make the query search results this: for each Pin, show the description
This obviously is not working, but any suggestions on how to get the above to display?
select p.description ,c.title, u.name from PushPin p,CorkBoard c, User u
where c.email=u.email and c.email =p.email and c.boardID = p.boardID
order by p.description
Yes, this will require you to join the three tables.
Something like the below code should work.
Just defining the Foreign key relations does not mean you would not need to join while querying.
SELECT PP.description, CB.title, U.name
FROM PushPin PP JOIN CorkBoard CB ON PP.boardID = CB.boardID
JOIN USSER U ON PP.email = U.email
WHERE description like '$search'
ORDER BY description;

issue selecting from many-to-many

my db is very simple:
CREATE TABLE Account (
accountId int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
PRIMARY KEY (accountId)
);
CREATE TABLE Manager (
managerId int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
PRIMARY KEY (managerId)
);
CREATE TABLE ManagerAccount(
id int not null auto_increment,
managerId int not null,
accountId int not null,
primary key(id),
foreign key(managerid) references Manager (ManagerID),
foreign key(accountId) references Account (AccountID)
);
Now, when i return an account object to the user I need to pull all the account associated with specific account
So I did something like:
select m.name
from manager m
inner join ManagerAccount ma on m.managerId = ma.id
inner join Account a on ma.id = a.accountId
where a.accountId = 1;
but this does not give me the answer I want, I only get one manager name and there are 3 managers associated with accountId 1...
you can see here:
inner join ManagerAccount ma on m.managerId = ma.id
inner join Account a on ma.id = a.accountId
should be
inner join ManagerAccount ma on m.managerId = ma.managerId
inner join Account a on ma.accountId = a.accountId
In your query, you have an foreign key relationship of ManagerAccount.accountId with Account (AccountID).
But you have mapped the primary key of ManagerAccount table with Account (AccountID).
SELECT
m.name
FROM
Manager m
INNER JOIN
ManagerAccount ma ON m.managerId = ma.managerId
INNER JOIN
Account a ON ma.accountId = a.accountId
WHERE
a.accountId = 1;

Unknown column 'R.movie_name' in 'on clause' for Inner join with subquery

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.

How to get distinct pairs for a table?

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

select count of each user privileges and pages from 4 tables mysql

This might be easy but I don't have enough experience with mysql, I have four tables:
employee
user
privilege
page
I want to select from these four tables the following:
emoloyeeName
UserId
count(privilege)
count(pages)
so I want my query to display each employee user name, number of granted user privileges and number of pages created by the user
my tables structure goes as follows:
CREATE TABLE IF NOT EXISTS `employee` (
`ID` int(11) NOT NULL,
`EMP_ENG_NAME_P1` varchar(15) DEFAULT NULL,
`EMP_ENG_NAME_P2` varchar(15) DEFAULT NULL,)
ALTER TABLE `employee`ADD PRIMARY KEY (`ID`);
CREATE TABLE IF NOT EXISTS `users` (
`ID` int(11) NOT NULL,
`USER_ID` varchar(30) DEFAULT NULL,
`USER_EMP` int(11) DEFAULT NULL,)
ALTER TABLE `users`ADD PRIMARY KEY (`ID`),
ADD UNIQUE KEY `USER_ID` (`USER_ID`),
ADD KEY `users_ibfk_1` (`USER_EMP`);
CREATE TABLE IF NOT EXISTS `privileg` (
`ID` int(11) NOT NULL,
`USER_ID` int(11) DEFAULT NULL,
`PAGE_ID` int(11) DEFAULT NULL,)
ALTER TABLE `privileg`ADD PRIMARY KEY (`ID`);
ALTER TABLE `privileg` ADD CONSTRAINT `privileg_ibfk_2`
FOREIGN KEY (`USER_ID`) REFERENCES `users` (`ID`)
ON DELETE CASCADE ON UPDATE CASCADE;
CREATE TABLE IF NOT EXISTS `pages` (
`ID` int(11) NOT NULL,
`userCreatorID` int(11) DEFAULT NULL,
`PAGE_ENG_DESC` varchar(100) DEFAULT NULL,)
I was able to construct two queries that display the the same result seperated once with the privilege count for each user and once with the page count for each user
first query:
select employee.EMP_ENG_NAME_P1, employee.EMP_ENG_NAME_P2, users.USER_ID, COUNT(privileg.ID)
from employee
INNER JOIN users on users.USER_EMP = employee.EMP_ID
INNER JOIN privileg on users.ID= privileg.USER_ID
GROUP BY users.ID
second query:
select employee.EMP_ENG_NAME_P1, employee.EMP_ENG_NAME_P2, users.USER_ID, users.ID, COUNT(pages.ID)
from employee
INNER JOIN users on users.USER_EMP = employee.EMP_ID
INNER JOIN pages on users.ID = pages.userCreatorID
GROUP BY users.ID
What I need now is to combine them together,like the following image
I use the following query:
select employee.EMP_ENG_NAME_P1,employee.EMP_ENG_NAME_P2, users.USER_ID, users.ID, COUNT(pages.ID), COUNT(privileg.ID)
from employee
INNER JOIN users on users.USER_EMP=employee.EMP_ID
INNER JOIN privileg on users.ID= privileg.USER_ID
INNER JOIN pages on users.ID= pages.userCreatorID
GROUP BY users.ID
but the count result is not correct, it is multiplied
any ideas?
try it-
SELECT emp.EMP_ENG_NAME_P1, emp.EMP_ENG_NAME_P2, usr.USER_ID, COUNT(DISTINCT prv.ID), COUNT(DISTINCT pgs.id)
FROM employee emp
INNER JOIN users usr ON usr.USER_EMP = emp.EMP_ID
INNER JOIN privileg prv ON usr.ID= prv.USER_ID
INNER JOIN pages pgs ON usr.ID= pgs.UserCreatorID
GROUP BY users.ID
Try:
SELECT employee.EMP_ENG_NAME_P1, employee.EMP_ENG_NAME_P2, users.USER_ID, COUNT(privileg.ID), COUNT(pages.ID)
FROM employee
INNER JOIN users on users.USER_EMP = employee.EMP_ID
INNER JOIN privileg on users.ID= privileg.USER_ID
INNER JOIN pages on users.ID = pages.userCreatorID
GROUP BY users.ID