Reputation: 1402
(This question is building on my other question here)
There are four tables in my database:
Users
(columns id
, dept_id
)Departments
(columns id
, deptStringName
)Absences
(columns id
, user_id
, type_id
)Absence_types
(columns id
, stringName
)At the moment there are 10 rows in the Departments
table and 12 rows in the Absence_types
table.
I'm trying to get a query that outputs ten tables, one for each department, with the types of absences and their counts next to the name, e.g., for the IT department:
+-----------+---+
| Sickness | 4 |
| Paternity | 7 |
| Maternity | 3 |
| ... | 6 |
+-----------+---+
I know the query to get these results. However, I'm wondering what is the best practice from a Software Engineering standpoint: do I hard-code the values in the WHERE
clause as I've done (dept.id = 1
) in the query below?
SELECT COUNT(abs.id) as AbsenceCount , absence_types.description FROM Absences abs JOIN Users u on u.id = abs.user_id JOIN Departments dept on dept.id = u.dept_id JOIN Absence_types on Absence_types.id = abs.type_id WHERE dept.id = 1 group by dept.description
Or do I use some other way to get the ID of a department? I can't think of a way in which I could write a Laravel script that would know how many departments there are and then run one query each per department.
EDIT: Example result could be like the one below (ideally), with A, B, C Absence Types for X, Y, Z Departments
+---+---+---+---+
| | A | B | C |
+---+---+---+---+
| X | 4 | 8 | 5 |
| Y | 7 | 9 | 4 |
| Z | 5 | | |
+---+---+---+---+
Upvotes: 1
Views: 253
Reputation: 31812
Try this way..
Initialize the table by getting all departments and all absence types:
$departments = DB::table('Departments')->pluck('deptStringName');
$absenceTypes = DB::table('Absence_types')->pluck('stringName');
$row = [];
foreach ($absenceTypes as $absenceType) {
$row[$absenceType] = 0;
}
$table = [];
foreach ($departments as $department) {
$table[$department] = $row;
}
This should create a 2D array like:
[
'X' => [
'A' => 0,
'B' => 0,
'C' => 0,
],
// ...
]
You can use NULL or an empty string instead of 0
if you like.
Now modify your query a bit. You need to group by departments and absence types.
$data = DB::select('
SELECT
d.deptStringName as department,
t.stringName as absenceType,
COUNT(a.id) as absenceCount
FROM Absences a
JOIN Users u ON u.id = a.user_id
JOIN Departments d ON d.id = u.dept_id
JOIN Absence_types t ON t.id = a.type_id
GROUP BY d.deptStringName, t.stringName
');
And fill the $table
with values fron the query:
foreach ($data as $row) {
$table[$row->department][$row->absenceType] = $row->absenceCount
}
Now the $table
shlould look like
[
'X' => [
'A' => 4,
'B' => 8,
'C' => 5,
],
'Y' => [
'A' => 7,
'B' => 9,
'C' => 4,
],
'Z' => [
'A' => 5,
'B' => 0,
'C' => 0,
],
]
Upvotes: 1