Querying friends for a user based on self-referencing table - mysql

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.

Related

How to show username if i have 2 tables, user and review

i am creating a restaurant review website. in my review table i have a foreign key called user_id and idk how to use it to display the username which is in the user table
my user table
my review table
so my question is how do i display the username from this? what mysql statement do i have to write. I am lost on what to do
Assuming you want to try and get the review text along with the user name from the corresponding user you can use a join to combine the info for example:
SELECT u.username, r.review_text
FROM reviews r
LEFT JOIN users u
ON (u.user_id = r.user_id)
I assumed the users table is called users and reviews table is called reviews but update those as necessary each is "aliased" as u and r respectively and then tables are joined
If the relationship between the two tables is mapped out correctly you should be able to run a query to fetch the name of each user. Try to avoid any N+1 query though

Relating 2 tables (users and groups) via IDs

I have 2 tables in my MySQL database for users and groups. I need to relate users with groups and groups with the users. The only way that came my mind is having a group_ids col for users and user_ids col for groups. I have to do like this because I will show users' groups that they registered in their profile and I will show registered users in groups' users pages.
In this option I need to to store group ids for users like "2,5,14" and same in groups for registered user ids like "22,24,15 ...".
It sounds okey to me but parsing IDs on back-end from commas is not sounds "professional". And also I have concerns for the performance when there is huge amounts of users in a group.
I know this seems like a opinion based question but I have a question and I think it is not opinion based.
Is there a usage like this in "data science"? I mean, is this a common usage or am I missing something here because I really can't think something else.
You could create a new table called user_group wich stores the user_id and group_id as foreign key and primary key
The you can get all groups by user with
SELECT item1, item2...
FROM user
INNER JOIN user_group on user.user_id = user_group.user_id
INNER JOIN group on user_group.group_id = group.group_id
WHERE user.user_id = id;

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.

Structuring up a database

I have some trouble setting upp a database. Not any coding problems but can't figure it out how to structure it.
The idea is that people will sign up on the site, and with SQL they will be in the table USER.
But the users will also availbaile to have a collection of handmade products so other users will see and rate their handmade products and see a lot of others information. So instead of having a table for each user, is there any easier way?
The product should only be "tied" to one user. No user would be able to have same identical product.
Like how does facebook work? I dont think every user have their one table for the information on use? The products could be like a picture. So every album dosen't have a table? Right?
Having separate table for each user is intolerable and completely wrong according to relational database model!
The goal you want to achieve is actually quite a basic thing in DB structuring, try reading some tutorials in that topic.
With a table USER and PRODUCT and properly set key fields, you'll be able to get the right form.
USER: user_id, << user details >>
PRODUCT: product_id, user_id, rank, << other product details >>
So with a query below, you'll be able to get all products of your users.
SELECT *
FROM db.user u
(LEFT) JOIN db.product p
ON u.user_id = p.user_id
The usual SQL approach is to create a table for the users and a table for the products. The products table should have a row "user" which contains the user id (or something else identifying the user). You might want to assign an ID to each user (e.g. autoincrement int) and use it.
You can then select all products of a given user:
SELECT * FROM products WHERE user = 723;
Or you might want to find the name of a user who made a product:
SELECT name FROM users WHERE rowid = (SELECT user FROM products WHERE product_name = 'Kitchen Chair');
By the way, I'd always use lowercase names for tables and rows in SQL.

'Likes' system database

I am developing web application where I have to implement 'Likes' system as facebook has. Application will have a few categories of products that customer can 'like'. So I have started to create database, but I stuck on one obstacle. As I understand there are two ways of doing this:
First. Create one database table with fields of "id, user_id, item_category, item_id". When user click 'like' button information will be saved in this table with various categories of products (item_category).
Second. Create several tables for certain categories of item. For instance, "tbl_item_category_1, tbl_item_category_2, tbl_item_category_3" with fields of "user_id, item_id".
Would be great to get more insight about best practices of this kind database structures. Which works faster? and more logical/practical? I will use only several categories of items.
I would go with the first version with a table structure similar to this:
User Table: PK id
id
username
Category Table: PK id
id
categoryname
Like Table: PK both user_id and catgory_id
user_id
category_id
Here is a SQL Fiddle with demo of table structure with two sample queries to give the Total Likes by user and Total Likes by category
The second one - creating multiple tables is a terrible idea. If you have 50-100 categories trying to query those tables would be horrible. It would become completely unmanageable.
If you have multiple tables trying to get a the total likes would be:
Select count(*)
from category_1
JOIN category_2
ON userid = userid
join category_3
ON userid = userid
join .....
Use one table, no question.
The first method is the correct one. Never make multiple tables for item categories, it makes maintaining your code a nightmare, and makes queries ugly.
In fact, the general rule is that anything that is dynamic (i.e. it changes) should not be stored as a set of static objects (e.g. tables). If you think you might add a new type of 'something' later on, then you need a 'something' types table.
For example, imagine trying to get a count of how many items a user has liked. With the first method, you can just do SELECT COUNT(*) FROM likes WHERE user_id = 123, but in the second method you'd need to do a JOIN or UNION, which is bad for performance and bad for maintainability.
The first method is the correct one. Because you dont know how many categories you will be having and it is very difficult to get the data.