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;
Related
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 am implementing a simple follow/followers system in MySQL. So far I have three tables that look like:
CREATE TABLE IF NOT EXISTS `User` (
`user_id` INT AUTO_INCREMENT PRIMARY KEY,
`username` varchar(40) NOT NULL ,
`pswd` varchar(255) NOT NULL,,
`email` varchar(255) NOT NULL ,
`first_name` varchar(40) NOT NULL ,
`last_name` varchar(40) NOT NULL,
CONSTRAINT uc_username_email UNIQUE (username , email)
);
-- Using a middle table for users to follow others on a many-to-many base
CREATE TABLE Following (
follower_id INT(6) NOT NULL,
following_id INT(6) NOT NULL,
KEY (`follower_id`),
KEY (`following_id`)
)
CREATE TABLE IF NOT EXISTS `Tweet` (
`tweet_id` INT AUTO_INCREMENT PRIMARY KEY,
`text` varchar(280) NOT NULL ,
-- I chose varchar vs TEXT as the latter is not stored in the database server’s memory.
-- By querying text data MySQL has to read from it from the disk, much slower in comparison with VARCHAR.
`publication_date` DATETIME NOT NULL,,
`username` varchar(40),
FOREIGN KEY (`username`) REFERENCES `user`(`username`)
ON DELETE CASCADE
);
Lets say I want to write a query that returns the 10 latest tweets by users followed by the user with username "Tom". What is the best way to writhe that query and return results with username, first name, last name, text and publication date.
Also if one minute later I want to query again 10 latest tweets and assuming someone Tom follows tweets during that minute, how do I query the database to not select tweets that have already shown in the first query?
To answer your first question:
SELECT u1.username, u1.first_name, u1.last_name, t.text, t.publication_date
FROM Tweet t
JOIN User u1 ON t.username = u1.username
JOIN Following f ON f.following_id = u1.user_id
JOIN User u2 ON u2.user_id = f.follower_id
WHERE u2.username = 'Tom'
ORDER BY t.publication_date DESC
LIMIT 10
For the second part, simply take the tweet_id from the first row of the first query (so the latest tweet_id value) and use it in the WHERE clause for the next query i.e.
WHERE u2.username = 'Tom'
AND t.tweet_id > <value from previous query>
To get latest 10 tweets for Tom:
select flg.username, flg.first_name, flg.last_name, t.tweet_id, t.text, t.publication_date
from user flr
inner join following f on f.follower_id = flr.user_id
inner join user flg on flg.user_id = f.following_id
inner join tweet t on t.username = flg.username
where flr.username = 'Tom'
order by tweet_id desc
limit 10
To get the next 10 tweets, pass in the max tweet_id, and apply an additional condition in the where clause:
where flr.username = 'Tom'
and t.tweet_id > <previous_max_tweet_id>
I have a table of ParentsSchoolContact, which a parentId have foreign key to the parentId:
CREATE TABLE ParentsSchoolContact (
contactId int NOT NULL AUTO_INCREMENT,
parentId int NOT NULL,
name varchar(60) NOT NULL,
age varchar(60) NOT NULL,
PRIMARY KEY (contactId),
FOREIGN KEY (parentId) REFERENCES Parent(parentId)
);
and I have a parent and contact table that keeps the relation between a kid and a parent:
CREATE TABLE ParentAndContact (
parentId int NOT NULL,
contactId int NOT NULL,
PRIMARY KEY (contactId, parentId)
);
I want to get all the contacts related to a specific parent that i have its id, would that be the right query?
SELECT c.name, c.age
FROM ParentsSchoolContact c
INNER JOIN ParentAndKid pc ON pc.contactId = c.contactId
AND c.parentId = myParentVariable
AND pc.parentId = myParentVariable
wanted to make sure this query dosent fall in some case you could think about :)
thanks!
For me, i see that the ParentAndContact table is redundant. Usually the Parents details are in one table and ContactID/Kids details are in another table (having attributes eg. courses which the kids enrolled, details of the kids).
Assuming that you want to get all the contacts related to a specific parent that you have its id from the available tables (ParentsSchoolContact,ParentAndContact), You can just write a simple query to retrieve the information from ParentsSchoolContact table as of below:-
select contactId, parentId, name, age
from ParentsSchoolContact
where parentId = myParentVariable
Do let me know if i miss out anything.
I have three tables...users, user_info, and quota_levels. They look like this:
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(31) NOT NULL,
password VARCHAR(33) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE user_info (
userID INT UNSIGNED NOT NULL,
firstName VARCHAR(32),
lastName VARCHAR(32),
phone CHAR(14),
address VARCHAR(128),
birthdate DATE,
misc TEXT,
quotaLevel VARCHAR(32),
PRIMARY KEY (userID)
);
CREATE TABLE quota_levels (
quotaLevel VARCHAR(32) NOT NULL,
quota1 INT NOT NULL,
quota2 INT NOT NULL,
PRIMARY KEY (level)
);
Every user will have an entry in the users table, but not necessarily in the user_info table. Each user in the user_info table has a quotaLevel corresponding to the quotaLevel column in the quota_levels table. Possible values for quotaLevel are BRONZE, SILVER, GOLD, and PLATINUM.
I could go into a long explanation of why it is set up this way, but it would be quicker to just say that this structure cannot be changed.
If the user exists, I want to get the quota1 value of their quotaLevel. If the user doesn't exist, the quota1 value for BRONZE should be returned.
I want to do this with ONE query. Can it be done and how?
SELECT u.Name,
COALESCE(ql.quota1, (SELECT quota1 FROM quota_level WHERE quotaLevel = 'BRONZE'))
FROM users u
LEFT JOIN user_info ui
INNER JOIN quota_level ql
ON ui.quotaLevel = ql.quotaLevel
ON u.id = ui.userID
What I am trying to do is create a comments section for a website,
The comments consist of a user's name, email and comment. I store this data in the 'comments' table
CREATE TABLE `comments` (
`commentid` int(5) NOT NULL auto_increment,
`user` varchar(40) NOT NULL default '',
`email` varchar(100) NOT NULL default '',
`comment` text NOT NULL,
PRIMARY KEY (`commentid`)
)
What i want to do is execute a query that grabs all this data but also checks the email address in the 'users' table to see if it exists. If it does, grab the avatar from the 'misc' table. If the email doesn't exist in the 'users' table, it's just left blank.
At the moment with the query i tried, it only grabs the data from the 3 tables if the email exists in the 'users' table. I have another comment which as anonymous user left but that's not getting grabbed by the query.
CREATE TABLE `users` (
`userid` int(25) NOT NULL auto_increment,
`email` varchar(255) NOT NULL default '',
`username` varchar(25) NOT NULL default '',
PRIMARY KEY (`userid`)
)
CREATE TABLE `misc` (
`miscid` int(4) NOT NULL auto_increment,
`userid` varchar(3) NOT NULL default '',
`avatar` varchar(100) NOT NULL default '',
PRIMARY KEY (`miscid`)
)
I am pretty sure i need a nested select as a column name so that if there is an email it displays there...if not it's left blank.
EDIT:
Made the table structures how it should be.
This is a query I have just tried but it only displays a row which has an email address. there should be another without email address
SELECT c.comment, c.user, av.avatar
FROM comments c
INNER JOIN users u ON c.email = u.email
LEFT OUTER JOIN (
SELECT userid, avatar
FROM misc
) AS av ON av.userid = u.userid
If I correctly understood your issue, the problem is that you are using an INNER JOIN between comments and users, which means that it will only return matching rows on email. Thus the reason why it does not return comments that are without email addresses or non-matching email addresses.
Replace your INNER JOIN with a LEFT JOIN. Try out this query:
SELECT `c`.`comment`, `c`.`user`, `m`.`avatar`
FROM `comments` `c`
LEFT JOIN `users` `u` ON `c`.`email` = `u`.`email`
LEFT JOIN `misc` `m` ON `m`.`userid` = `u`.`userid`;
Hope that should help you get all comments.
Not really sure what your desired output, how you get the right misc for a given user, but here is the general idea
SELECT userid, email, username, IF(email<>'',(SELECT avatar from misc where miscid = users.userid),null) avater FROM users;
this is a more readable version
SELECT
userid,
email,
username,
IF(email<>''
,/*then*/(SELECT avatar from misc where miscid = users.userid)
,/*else*/null)
as avater
FROM users;
Please provide a clear list of your tables, and an example desired output, and we can better assist.
The final desired example output is very helpful when designing MySQL statements.
SELECT * FROM comments LEFT JOIN users
ON users.email=comments.email
Not really sure if this is what you mean, but I guess you just want some extra columns in your query result with the email address (empty if not available) and avatar (empty if not available), if that's right you can work with a LEFT JOIN.
SELECT
c.*,
u.email,
m.avatar
FROM
comments as c LEFT JOIN
users as u ON (u.userid = c.user) LEFT JOIN
misc as m ON (m.miscid = u.userid)
Please not that the column names you are using are quite weird and inconsistent; use just the name id for the id of the column, and reference only to those id's in other models.
No, what you actually need is LEFT OUTER JOIN.
Its purpose is exactly what you need - when joining two (or three) tables on some key and the left table has no correspondent key it's columnsare filled with NULL in the result set for that key.