Question

1- Users may have many classrooms 2- Classrooms may have many users 3- Users may have many payments in their classrooms

how can I get a classroom payments through its users with SQL?

how can I get sum of the payments of a user per classroom?

-- Payments Table: --
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id    | int(11)      | NO   |     | NULL    |                |
| amount     | int(11)      | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

-- Users Table: --
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

-- Classrooms Table: --
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

-- Classroom_User Table: --
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id     | int(11)      | NO   |     | NULL    |                |
| classroom_id| int(11)      | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
Was it helpful?

Solution

Without testing, I'd say:

SELECT p.amount, u.name, c.name
FROM payments p, users u, classrooms c, classroom_user ct
WHERE   ct.user_id = u.id
    AND ct.classroom_id = c.id
    AND u.id = p.user_id

However: it's not clear what your tables are about. For instance: one record in the payments table can result in multiple records in the result set, namely when there are multiple records in the classroom_user table for the same user.

Something in your database design feels wrong, but it's hard to tell what's wrong without more info.

Suppose that you want to get the payments for each classroom. In that case, your database design is wrong because you only know the amount each user paid in total, not the amount the user paid per classroom.

The payments table should look like this:

+-------------------+--------------+------+-----+---------+----------------+
| Field             | Type         | Null | Key | Default | Extra          |
+-------------------+--------------+------+-----+---------+----------------+
| id                | int(11)      | NO   | PRI | NULL    | auto_increment |
| classroom_user_id | int(11)      | NO   |     | NULL    |                |
| amount            | int(11)      | NO   |     | NULL    |                |
+-------------------+--------------+------+-----+---------+----------------+

In that case, you'd have:

SELECT c.name, u.name, p.amount
FROM payments p, users u, classrooms c, classroom_user ct
WHERE   p.classroom_user_id = ct.id
    AND ct.classroom_id = c.id
    AND ct.user_id = u.id

Or, if you want to get the total amount per classroom:

SELECT c.name, SUM(p.amount)
FROM payments p, classrooms c, classroom_user ct
WHERE   p.classroom_user_id = ct.id
    AND ct.classroom_id = c.id
GROUP BY c.id

Note that I didn't test this. I don't have your database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top