How to display information from a referencing table? - mysql

There is probably a very simple solution to this, but I couldn't figure out an appropriate way to google it.
I have three tables in my database.
The first one is "customer" and it has (ID, Name, Username etc)
The second one is "attraction" and it has (AttractionID, Name, Location, etc..)
The tird one "favourites" is made in order for the user to save favourites from the second table with the user ID from the first one:
Here is the third table:
CREATE TABLE Favorites (
FavID INT NOT NULL,
ID INT NOT NULL,
AttractionID INT NOT NULL,
PRIMARY KEY (FavID),
FOREIGN KEY (ID) REFERENCES customer(ID),
FOREIGN KEY (AttractionID) REFERENCES attraction(AttractionID)
);
I can insert into the table but what sql query do I need to use in order to show information from the referencing tables?
Lets say the user has saved their user ID and favourite attraction ID to the favourite table, how can I display the name and location from the attraction table that corespond to the foreign key attractionID saved in the favourites table?
Thanks

You should use JOIN for it:
SELECT * FROM Favorites f
INNER JOIN Attraction a ON f.AttractionId = a.AttractionId
INNER JOIN customer c ON f.Id = c.id
f, a and c are just aliases to make the referencing simpler, you could also write
SELECT * FROM Favorites
INNER JOIN Attraction ON Favorites.AttractionId = Attraction.AttractionId
INNER JOIN customer ON Favorites.Id = customer.id
or with AS, which makes it a bit more clear (but longer, so I prefer the first way)
SELECT * FROM Favorites AS f
INNER JOIN Attraction AS a ON f.AttractionId = a.AttractionId
INNER JOIN customer AS c ON f.Id = c.id

Related

Referencing Two Tables in SQL DB

I'm new to SQL, how could I answer the following question? Do I use join?
Thank you so much.
What are the names and home cities for people searched for the word "drain"?
.schema is below:
CREATE TABLE `users` (
`id` INTEGER,
`name` VARCHAR,
`email` VARCHAR,
`city` VARCHAR,
`state` VARCHAR,
`last_visit` DATE,
`page_views` INTEGER,
PRIMARY KEY (`id`)
);
CREATE TABLE `search_terms` (
`id` INTEGER,
`word` VARCHAR,
PRIMARY KEY (`id`)
);
select u.name, u.city
from users u
inner join search_terms st on st.id = u.id
where st.word = 'drain'
I hope this helps.
You do need to join search_terms table with users table. I assume the search_terms.id is referencing to users.id.
Linking them both, will give us the results of the search terms for each user.
from there you can add more filters (WHERE conditions) to have more specific results.
So, to get the names and the home cities for each user you need to select name and city from users table, then join search_terms table and link id columns to know what words that each user has used in the search.
The query should be something like this :
SELECT name, city
FROM users
LEFT JOIN search_terms ON search_terms.id = users.id
WHERE
search_terms.word LIKE 'drain';
You could use a JOIN or a sub-query. Here's the basic strategy:
Get the id values that match what you're looking for
Look up any other info for those id values
.
SELECT name, city
FROM users usr
INNER JOIN search_terms stm ON usr.id = stm.id
WHERE stm.word = 'drain';
or ...
SELECT name, city
FROM users
WHERE id IN (SELECT id FROM search_terms WHERE word = 'drain');

How to select entries WITHOUT matching dependents in same table

What I have is a table containing people. Some people are primary entries and others are secondary (partners, children etc)
The primary entries have a 'cls' of say 3 (where cls is a column name). The secondary entries have different cls, say 4. The secondary entries also have a 'primary' field linking them back to the unique ID of their primary person. (primary field is empty on primary people)
What I want to do is select all primary entries that do not have anyone linking back to them.
Here's where I got to, but it is obviously not right. I figure there is some other form of JOIN that I need? (pp1 is referring to secondaries and pp2 is referring to primaries)
SELECT pp2.per_ID
FROM person pp1 LEFT OUTER JOIN person pp2 ON pp1.primary = pp2.per_ID
WHERE pp1.cls = 4 AND pp2.cls =3
AND pp2.primary IS NULL;
.
TABLE person
COLUMN per_ID, cls, primary
SELECT p.* FROM person as p
LEFT JOIN person AS s
ON p.`primary` = s.per_ID
WHERE s.per_ID IS NULL AND p.cls =3

SQL - How do I get name using a number from a different table?

Below is my create tables for a database using SQL.
I can't figure out how to get a name displayed for both ID and LIKED from the likes table.
This assignment should be simple, be able to display the names of people that like each other. There is a data entry form that requires IDs to be entered for the people that like each other, but then I have to display the names of both of the people that like each other.... I hope I didn't make this confusing.
Is it possible for some SQL code to display the names of who likes who.
CREATE TABLE person
(
ID INT PRIMARY KEY,
NAME VARCHAR(50)
) engine=innodb;
CREATE TABLE likes
(
ID INT,
LIKED INT,
constraint likesPK primary key(ID,LIKED),
constraint personFK foreign key(ID) references person(ID)
on delete cascade on update cascade,
constraint nameFK foreign key(LIKED) references person(ID)
on delete cascade on update cascade
) engine=innodb;
Example of what I have tried to do but needs one more column to display the person "LIKED":
select B.id, B.name, A.lIKED from likes A, person B where A.id=B.id AND A.id = 1;
First, I wave my finger in your general direction. Programming requires precision and your phrase, "using sql" was vague. If you meant sql server say so. In fact, edit your post and add the appropriate tag.
Second, your on delete cascades are in the wrong place. In fact, in this scenario, on delete cascades are probably a very bad idea.
Third, what was that again? Oh yes your question. How do I show people who like each other? Probably something like this:
select p1.whatever, p2.whatever
from person p1 -- this would be me
join likes l1 on p1.id = l1.id -- this is who I like, which is you
join likes l2 on l1.liked = l2.id -- this is who you like, which is me
join person p2 on l2.id = p2.id -- this is you
etc
By the way, I didn't think it was simple.
try this
select b.id, b.name, (select name from person where id = a.liked)
from likes a join person b
on a.id = b.id
where b.id = some id AND b.id = a.id
Seems like your like table should have two references to the person table (making it an intermediate/pivot table); basically, one "like-ee" and one "like-or". So like should probably look like this:
like
--------------
ID int
PersonWhoLikedID int
PersonWhoWasLikedID int
Then your query turns into this:
SELECT B.name, C.name AS `Liked Person`
FROM likes
LEFT JOIN person B ON likes.PersonWhoLikedID = B.ID
LEFT JOIN person C ON likes.PersonWhoWasLikedID = C.ID

MySQL one table inner join with 3 different entity tables

I got 4 tables, Email_Company_Contact_Ref table is the table which linked with Email, Company, and Contact.
**Email_Company_Contact_Ref**
id = primary key
email_id = reference to Email.`id`
ref_id = it can be Company.id / Contact.id
table = reference from which table name
I try to use left join to get my output, but I got duplicated result. If I try inner join, I will not get any result at all, it is because Company and Contact this two tables does not have any thing common.
This is the output I would like to complete.
I able to use UNION to get the output, but it not really effective. I am thinking it should be a way to get the output result.. Please help.
Thanks!
Here is my mysql answer, hope this can help
SELECT e.email, r.table, c1.name AS company_name, c2.name AS contact_name
FROM email_company_contact_ref r
JOIN email e ON e.id = r.email_id
LEFT JOIN company c1 ON (c1.id = r.ref_id AND r.table = 'company')
LEFT JOIN contact c2 ON (c2.id = r.ref_id AND r.table = 'contact')
GROUP BY r.table, e.email
I don't think it can be done without a UNION. Here's my suggestion.
SELECT email_address, eccr.table table, company_name, contact_name
FROM Email e, Email_Company_Contact_Ref eccr,
(SELECT "Company" table, id, company_name, NULL contact_name
FROM Company
UNION ALL
SELECT "Contact" table, id, NULL company_name, contact_name
FROM Contact) cc
WHERE e.id = eccr.email_id
AND eccr.table = cc.table
AND eccr.email_id = cc.id
I'm not getting the ref_id part... Is it a foreign key? Or is that the primary key for the Email_Company_Contact_Ref table?
I would think you'd want to put the reference for the Email table in the Company and Contact tables. If you need more than one emails for them, then you should create two join tables: Company_Email and Contact_Email. Your current design (with references to table names as values for a column) is bad SQL design -- just because things like RoR promote it, it won't get any better.
With proper design, the equivalent of that complicated query would look something like:
CREATE TABLE Company_Email (company_id integer, email_address varchar(100),
FOREIGN KEY company_id REFERENCES Company (id));
CREATE TABLE Contact_Email (contact_id integer, email_address varchar(100),
FOREIGN KEY contact_id REFERENCES Contact (id));
SELECT email_address, 'Company' AS kind, company_name AS name
FROM Company_Email ce JOIN Company c ON company_id = c.id
UNION
SELECT email_address, 'Contact', contact_name
FROM Contact_Email ce JOIN Contact c ON contact_id = c.id;
If you can't change it, you'll have to do the UNION along the lines Barmar explained it.
Or, you can do a SELECT DISTINCT to get rid of the duplicates from your left joined query.

How to JOIN two FKs from a table to another table?

I have a table of many-to-many relationships as:
Table relationship:
relationship_id,
first_user REFERENCES users(user_id),
second_user REFERENCES users(user_id),
Table users:
user_id,
other user information
To read friends of a given user (which can be in first_user or second_user), I need to JOIN two tables (relationships and users), but two columns of the table relationships are FK
Question 1: How can I JOIN two tables to use both FKs?
I have a table for pending requests which is similar to the table relationships. Upon approving a request, it will be deleted from requests and INSERTed into relationships.
Question 2: How can I JOIN three tables to retrieve connection and pending requests in one query.
You will have to give the instances of the "users" table aliases, so you can refer to them serparately:
SELECT u1.*, u2.* FROM relationship r
JOIN users u1 ON (u1.user_id = r.first_user)
JOIN users u2 ON (u2.user_id = r.second_user)
To select both from requests and relationships, you can use a UNION:
SELECT u1.*, u2.* FROM relationship r
JOIN users u1 ON (u1.user_id = r.first_user)
JOIN users u2 ON (u2.user_id = r.second_user)
UNION
SELECT u1.*, u2.* FROM requests r
JOIN users u1 ON (u1.user_id = r.first_user)
JOIN users u2 ON (u2.user_id = r.second_user)
To use both foreign keys, you need two joins (one for each):
select *
from relationship r
inner join users u1 on (u1.user_id = r.first_user)
inner join users u2 on (u2.user_id = r.second_user)
The {relationship_id, first_user, second_user} table contains a repeating group.
Just remove one of them (that makes relationship_id non-unique) and add a surrogate key (or add userid to the primary key).
CREATE TABLE relationships
( id INTEGER NOT NULL PRIMARY KEY
, relationship_id INTEGER NOT NULL
, user_id INTEGER NOT NULL REFERENCES users(user_id)
);
It would be a nice homework assignment to try to generate constraints for this construct.
Another way (for binary relations like marriages) is to put the "significant Other" link in the users table:
CREATE TABLE lusers
( luser_id INTEGER NOT NULL PRIMARY KEY
, magnificent_other INTEGER REFERENCES lusers (luser_id)
...
);
As a side effect, this will also make bigamy impossible.
Again: nice homework assignment to implement the constraints.