Help needed to construct a SQL query - mysql

Need your help to get the list of suggested friends (who aren't friends of the current user but are friends of 2 or more of the current user's friends). The primary ordering should put people at the same school at the top, and the secondary ordering should put people with more common friends (that is, the number of people who are friends of that person and the current user) near the top.
Users:
user_id PK,
user_name
Profiles:
user_id PK,
school_name,
...
Friendships:
id PK,
user_id FK,
friend_id FK
Thank you in advance.
Joe
This is not a homework question. I am currently working on a site and my solution seems not efficient enough. That's why I need you suggestions. Thanks.

(I'm assuming HW here.)
Seems like if you queried for a list of all of your friends' friends, and checked for the friends-of-friends that weren't unique in that list, you'd be getting somewhere.

Related

Mysql table multiple foreign key

I have three table users, cars and enquiries and their design is like:
users:
id ,name, email
cars:
id,user_id,name
Enquiry:
id, car_id,description
I just want to know that should I have to keep user_id in Enquiry table or not.As I know that i can fetch user detail with reference of car_id of cars table.what is the best way to manage these kind of things.
Thanks in advance.
If you remove the user_id from Enquiry table, you have an implicit assumption in your design that the enquiry is aways created by the car owner.
Is this assumption acceptable to you?
This may be very subjective, but talking about correctness, my opinion is that you should keep the user_id because Enquiry itself is an entity and should have its own owner.
It is based on your reports but I would say, you will not require the extra user_id as everytime you would be joining all the table for detailing the user info and car info with the Enquiry taken.

Querying friends for a user based on self-referencing table

I have a user table and a self-referencing table so users can be assigned as friends to each other. The table looks like this:
(source: image.frl)
I want to query the table and get back all the friends for a particular user (for example by user id). I'm not sure how to query it in a way that it knows that it should look for all the friend id's for the user id and lookup all the users that are associated with those friend id's in the user table.
Can anyone shed a light on how this can be done? I'm using MySQL.
The simple answer to your question (a look up by user_id) is this
SELECT friends.*
FROM user AS friends
JOIN user_has_friends ON friends.id = user_has_friends.friend_id
WHERE user_has_friends.user_id = *ID HERE*
You'd have to add another join to the users table if you wanted to look up by first_name or any other column.

How do I join all rows with the same name in one table using MYSQL?

Suppose I have a database called clubmembership that has a column for names, a column for clubs, and a column for the role they play in that club. The name Margrit would be in the column name many times, or as many times as she is in a club. If I want to see which people are members of the sewing club my query might look something like this:
SELECT DISTINCT NAME FROM CLUBMEMBERSHIP
WHERE CLUB=’SEWING’
AND ROLE=’MEMBER’;
My problem is that I can't figure out a query for who is not in the sewing club. Of course the simple 'not in' clause isn't working because there are plenty of rows which sewing does not appear in. In this database if someone is not in the sewing club, sewing does not appear under club so I imagine there is a way to join the different rows with the same name under 'name' and then potentially use the 'not in' clause
I hope this was a good explanation of this question. I have been struggling with this problem for a while now.
Thanks for your help!
Nicolle
This is not something that can be solved by just changing the existing code, it is to do with the database design.
Database normalisation is the process of sorting out your database into sensible tables.
If you’re adding a person many times, then you should create a table called members instead. And if there is a list of clubs, then you should create a clubs table.
Then, you can create a table to join them together.
Here’s your three tables:
members
-------
id (int)
name (varchar)
clubs
-------
id (int)
name (varchar)
memberships
-------
member_id (int)
club_id (int)
Then you can use joins in MySQL to return the information you need.
Stack Overflow doesn’t like external links as the answer should be here, but this is a huge topic that won’t fit in a single reply, so I would briefly read about database normalization, and then read about ‘joining’ tables.
If I understand you correctly, you wanted to list all names that is not a member of SEWING. The Inner query will get all Names that are member of SEWING, however, the NOT EXISTS operator will get all Names that are not found in the inner query.
SELECT DISTINCT C.NAME
FROM CLUBMEMBERSHIP C
WHERE C.ROLE = 'MEMBER'
NOT EXISTS
(
SELECT NULL
FROM CLUBMEMBERSHIP D
WHERE D.CLUB='SEWING'
AND D.ROLE='MEMBER'
AND C.NAME = D.NAME
)
Here's a Demo.

(MYSQL) Performances in checking if an ID already exists (for ex. in a Poll voters table)

I would like to know which is the best when I want to check if somebody already participated to a members related event (like a poll):
Imagine that I have a table that stores all the voters votes. Over time, it can reach a very big size (10000+ entries/votes for 500 different polls).
When I want to check if a member has already voted to my new poll, what's the best? :
1/ Make a SELECT or a COUNT on the "10000+ entries VOTERS table" to see if said USERID already voted to my new poll.
2/ Having a TEXT columns in my POLL_main_infos Table where i stock/CONCAT the USERIDS like these:
"1,15,42,12,523,8521,7444, etc etc."
And to check, I get that columns as a variable then in my PHP script, I use a REGEX to check if a USERID is already present in it (like looking for ",42,", meaning the USER with the ID "42" already participated to said poll.
Also, if the second solution is the best, should I stock the IDS in a text column or a BLOB?
Anyways, thank you very much in advance!
In a Relational Database system it's usually best to store data normalized, so no list of user ids, never.
So using Holmes IV suggested tables it's a simple:
SELECT 'User already voted'
WHERE EXISTS
(
SELECT * FROM Participation
WHERE PollId = 123
AND UserId = 456
)
With an appropriate index (a UNIQUE index if a user might vote only once per poll) this will be very fast regardless of the number of rows.
How much freedom do you have with this? I would say you need 3 tables, 1 for each : Polls, Voters, Participation . In the Polls table you store Poll_ID and Poll_Description. In voter you store all Voter_ID and any other voter information you might have. Then in the participation you store, Poll_ID,Voter_ID, and results or simply a date of when they participated. Then when you want to see such information you query the 3rd table, and join it on the other too for the specifics
The best way to check if a user already voted is to query the Polls_Voters tables in your setup it would be
Select *
from Polls_Voters
where Voter_ID = 'ID of voter you are looking for'
and poll_id = 'ID of poll you wish to see if they voted in'

Did I overdesign my MySQL database (users/companies/products)?

I'm new to database design,
please give me advice about this.
1 When should I use a composite index?
im not sure what does index does, but
i do know we should put it when it
will be heavly loaded like for WHERE
verified = 1 and in search like
company.name = something. am i right ?
2 MySQL indexes - how many are enough?
is it just enough ?
3 Database Normalization
is it just right?
Thanks.
edit*
rules.
each users( company member or owners ) could be a member of a
company
each company have some member of users.
there are company admins ( ceo, admins) and there are company members
( inserts the products )
each company can have products.
for the number 3 i will add a bit at users_company
- 1 is for admin
- 0 is for members
Looks good, well normalised, to me at least.
I notice that each product can only belong to one company. If that's what you intended that's fine, otherwise you could have product have its own PID and have a product_company relation table, which would let more than one company sell a particular product. Depends who administers the products I guess.
I did notice that the user table is called 'users' (plural) and the others are singular ('company', 'product'). That's only a minor thing though.
The only comment I have is that you may want to consider just adding a mapping_id column to your users_company table and making CID and UID foreign keys, and add a UNIQUE constraint.
This way you can have a distinct Primary Key for records in that table which isn't dependent on the structure of your other tables or any of your business logic.