Need help building an odd Sequelize query - mysql

Some context:
I have two tables: challenges and participants.
challenges table columns: id, userId, and name.
participants table columns: id, userId, and challengeId
The userId column on the challenge table indicates ownership of a challenge.
The participants table is simply an association table to keep track of users who have joined challenges.
challenges.hasMany(participants)
participants.belongsTo(challenges)
The owner of a challenge may or may not be a participant.
My question:
How can I construct a single Sequelize query to find all owned OR joined challenges for a specific user?
Example Data:
challenges
+----+--------+-------------+
| id | userId | name |
+----+--------+-------------+
| 1 | 2001 | Challenge 1 |
| 2 | 2002 | Challenge 2 |
+----+--------+-------------+
participants
+----+--------+-------------+
| id | userId | challengeId |
+----+--------+-------------+
| 1 | 2001 | 1 |
| 2 | 2002 | 1 |
+----+--------+-------------+
Desired result of finding all owned OR joined challenges of user 2002:
challenges: [
{
id: 1,
userId: 2001,
name: "Challenge 1"
},
{
id: 2,
userId: 2002,
name: "Challenge 2"
}
]

Give this a try:
SELECT challenges.*
FROM challenges
LEFT JOIN participants
ON challenges.id = participants.challengeId
WHERE challenges.userId = 2002
OR participants.userId = 2002;

Related

Laravel Group and Show Popular Relation

If I have a users table with a column country and the user belongsToMany Categories, Is there a way I can group the users by country showing the most popular categories for each country?
For example:
Users
id | name | country
1 | UserA | Canada
2 | UserB | USA
3 | UserC | Canada
Categories
id | Name
1 | Housing
2 | Cooking
category_user
id | category_id | user_id
1 | 1 | 1
2 | 2 | 2
3 | 1 | 3
From the table you can tell that Housing is the most popular category in Canada. I can't seem to show that with code.
I've tried eloquent "with" function but it only just shows me category for a certain (1st?) user.
Any help would be greatly appreciated!
Edit:
Ersoy gave me a fantastic solution but it brought up a new problem which I didn't consider when posting the question. I have another table "payments" with a haveMany relationship where I sum all the amount column for each user. With the current join query, it duplicates the amount for each belongsToMany relationship resulting in wrong sum.
Payments
id | amount | user_id
1 | 500 | 1
2 | 200 | 2
3 | 150 | 1
4 | 100 | 3
return User::leftJoin('category_user as cu', 'users.id', '=', 'cu.user_id')
->join('categories as c', 'cu.category_id', '=', 'c.id')
->groupBy(['country', 'c.name'])
->get([
'users.country',
'c.name',
DB::raw('count(*) as total')
])
->groupBy('country')
->values()
->map(function (Collection $elt) {
return $elt->sortByDesc('total')->first();
});
it will print in the following format.
[
{
"country": "Canada",
"name": "Housing",
"total": 2
},
{
"country": "USA",
"name": "Cooking",
"total": 1
}
]

Sequelize - Matching all records of a given entity in mySQL database

I have three MySQL (v8) tables
TABLE 1:
students (contains details of all students)
- id
- full_name
- email
Records:
| id | full_name | email |
|----|-----------|-------------------|
| 1 | John | john#example.com |
| 2 | Adam | adam#example.com |
| 3 | James | james#example.com |
| 4 | Jane | jane#example.com |
TABLE 2:
courses (contains all courses)
- id
- title
Records:
| id | title |
|----|--------|
| 1 | PHP |
| 2 | Python |
| 3 | .Net |
| 4 | HTML |
TABLE 3:
student_courses (this table contains which student has subscribed to what courses)
- student_id
- course_id
Records:
| id | student_id | course_id |
|----|------------|-----------|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | 3 | 1 |
The problem I am facing here is I need to get a list of all students who have opted for both course ids 1 & 2, which in the above example is "John".
Using sequelize I have tried the following two where clauses, but both giving me incorrect results.
Option 1) This is giving me empty result set
where: {
course_id: {
[Op.and]: [1,2]
}
}
Option 2) This is returning "John" as well as "James". It shouldn't return "James" since he has subscribed to only course id 1.
where: {
course_id: [1, 2]
}
What am I missing here?
Thanks in advance
You can achieve N:M associations by using this, More information can be found here http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-belongsToMany
//add required associations
students.associate = (models) => {
students.belongsToMany(models.courses, {
through: 'student_courses',
foreignKey: 'student_id'
});
};
// now query the db like this
db.students.findAll({
where: { full_name : 'john'},
include: [{
model: db.courses,
where: {
id: {
[Op.and]: [1,2]
}
}
}]
})

database structure for multiple ingredients

Below I have a basic database for recipes. I want to have a table of ingredients that are static, and each time a user adds an ingredient 3 ids gets put into the recipe_ingredient table, 1 for the new recipe_ingredient, 1 for the recipe its for and 1 for the ingredient. I want to know if this is practical or what would be a good way to store ingredients for recipes.
---RECIPES--- ---INGREDIENTS---
+-> ID: ID: <-+
| NAME: NAME: |
| PHOTO: |
| |
| ---RECIPE_INGREDIENT--- |
| ID: |
+------+ RECIPE_ID: |
INGREDIENT_ID: +--------+
AMMOUNT:

Should I make 1 or 2 tables for Lecturers and Students in MySql? [duplicate]

This question already has an answer here:
Hierarchical database model
(1 answer)
Closed 8 years ago.
I am currently working on a project where you save the details of a lecturer and student.
I am not sure if I should use one table User or two tables Lecturer and Student.
When you log in as a lecturer you have special privileges as its a group management page for projects, on the group page when it loads that a student will not have. In User tbl there will be a column
status where on register, the page you can choose to be student or lecturer and enter a special
lecturer code. I am are using PHP with mySql.
In Summary, should I use 1 User table for both Student and lecturer, or have 2 separate Student and Lecturer tables.
Additional Information: 1 course could have many lecturers and students, but 1 student would have 1 course where as lecturer has many courses.
Great question!
It may seem over complicated, but if you want to scale this system, I highly suggest modeling this a little more "normalized". You are already on the right track by realizing that both lecturers and students are the same entity (people/users). The trick is that you should model "roles", and then model user's roles as well. That makes 3 total tables for this small portion of your model.
USERS USER_ROLES ROLES
+------------+ +----------+ +--------+
| id | <--> | user_id | /-->| id |
| login_name | | role_id | <--/ | name |
| etc | +----------+ +--------+
+------------+
users
======
id
login_name
etc
roles
=======
id
name
user_roles
===========
user_id
role_id
since
Sample Data
USERS
+----+------------+
| id | login_name |
+----+------------+
| 1 | Chris |
+----+------------+
| 2 | Cherri |
+----+------------+
ROLES
+----+------------+
| id | name |
+----+------------+
| 1 | Lecturer |
+----+------------+
| 2 | Student |
+----+------------+
USER_ROLES
+---------+---------+
| user_id | role_id |
+---------+---------+
| 1 | 1 | <-- Chris is a Lecturer
+---------+---------+
| 2 | 2 | <-- Cherri is a student
+---------+---------+
| 2 | 1 | <-- Cherri is also a lecturer
+---------+---------+
Use a single table with a field that indicates if it's a student or lecturer. It can be a simple integer column name "role" where role=0 means student and role=1 means lecturer.
This is simple, quick to implement, and meets the requirements.

retrieving data from two mysql tables where the second table depends on the first

I have two MySql tables:
users(id_user, name, age, gender ).
ways(#id_user,id_way, start, end, date).
What I want is to retrieve all the ways with their corresponding users details.
So my result would be like this:
id_way | start | end | date | id_user | name | age | gender
---------------------------------------------------------------------------
2 | place1 | place2 | 12/06/2013 | 145 | john | 28 | m
Have you tried JOIN?
SELECT ways.id_way, ways.start, ways.end, ways.date, users.*
FROM ways JOIN users USING (id_user)