PDO: group a property instead of duplicate lines - php

Good morning,
I have a request that return me several information for a reservation and each reservation can be linked to several room.
Is it possible to have an array of room instead of duplicate the line each time they are multiple rooms for a reservation.
What I want:
[
idReservation1 => [
"client_name" => "kévin titi",
"checkin" => "2017-08-08",
"d_checkout" => "2017-08-10",
"email" => "titi#gmail.com",
room_id => [1,2,3,9]//here I want an array
],
idReservation2 => [
"client_name" => "firstname lastname",
"checkin" => "2017-08-18",
"d_checkout" => "2017-08-20",
"email" => "toto#gmail.com",
"room_id" => [1,12,13,9]//here I want an array
]
]
if the idReservation is not the key does not matter, the important here is to have an array for room_id
I have looked all PDO fetch modes but they don't seems to match to my problem.
My request:
$prep = $this->pdo->prepare("
SELECT re.id as resId, re.client_name, re.d_checkin, re.d_checkout, re.mail, ro_re.room_id as room
FROM Reservation re
JOIN Room_Reservation ro_re ON ro_re.reservation_id = re.id
WHERE re.confirmed = false
");
Thanks

Assuming that you are working with MySql: the solution using GROUP_CONCAT function(to group room ids for each reservation):
$stmt = $this->pdo->prepare("
SELECT
re.id as resId, re.client_name, re.d_checkin, re.d_checkout, re.mail,
GROUP_CONCAT(ro_re.room_id SEPARATOR ',') AS room_ids
FROM
Reservation re
INNER JOIN Room_Reservation ro_re ON ro_re.reservation_id = re.id
WHERE re.confirmed = false
GROUP BY re.id
");
$stmt->execute();
// `room_ids` column will contain a string like "1,2,3,9"
$result = [];
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$row['room_ids'] = explode(',', $row['room_ids']); // converting string with room ids into array
$result[] = $row;
}

Related

MySQL sort by 0 and then from smallest to largest in medoo

I am trying to do a mysql sort that displays 0 first and then by the smallest number.
$query = "SELECT DISTINCT id FROM `items` WHERE `name`='Mag' AND `var`='Bl' ORDER BY atrow + 0 ASC"
How to write it in medoo?
$item = $database->select("items", "#id", [
"var[=]" => "Bl",
"name[=]" => "Mag",
"ORDER" => ["atrow" => "ASC"]
]);
This is not working properly.
You need a two tiered sort here. Assuming we use the following raw MySQL query:
SELECT DISTINCT id
FROM item
ORDER BY row != 0, row;
PHP code:
$item= $database->select("items", "#id", [ "ORDER" => Medoo::raw("`row` != 0, `row`")]);

Php mysql join to subarray with field names

I trying to join table using ONE query into sub array with column name => column value..
Short table(1) "users" structure with data:
user_id email ...
1 xxx#xx.xx ...
2 yyy#yy.yy ...
Short table(2) "users_permissions" structure with data:
user_id plugin_enter offers_view ...
1 1 0 ...
2 1 1 ...
If i use classic method - join left
SELECT `uperms`.*, `u`.*
FROM (`users` as u)
LEFT JOIN `users_permissions` as uperms ON `u`.`user_id` = `uperms`.`user_id`
I get classic output
[0] = array(
'user_id' => 1,
'email' => xxx#xx.xx,
'plugin_enter' => 1,
'offers_view' => 0
),
[1] = array(
'user_id' => 2,
'email' => yyy#yy.yy,
'plugin_enter' => 1,
'offers_view' => 1,
...
),
All i need is output into subarray as this:
[0] = array(
'user_id' => 1,
'email' => xxx#xx.xx,
'permissions => array(
'plugin_enter' => 1,
'offers_view' => 0
),
),
...
Is this possible to do with ONE query?
Table2 (permissions) contains about 60 columns. Is possible to CONCAT column's names with column value, if is joined to Table1 only one row?
MySQL doesn't have arrays or nested structures, so it's not possible to do this in SQL.
Change your query so you give all the fields from users_permissions a consistent naming style. Then you can use a PHP loop to collect all the array elements whose keys match that pattern into the permissions array.
Query:
SELECT u.*, up.plugin_enter AS perm_plugin_enter, up.offers_view AS perm_offers_view, ...
FROM users AS u
JOIN users_permissions AS up ON u.user_id = up.user_id
PHP:
foreach ($all_results as &$row) {
$permissions = array();
foreach ($row as $key => $value) {
if (strpos($key, 'perm_') === 0) {
$permission[substr($key, 5)] = $value;
unset($row[$key]);
}
}
$row['permissions'] = $permissions;
}
You could do it by concatenating all the column names and values in the table:
SELECT u.*, CONCAT_WS(',', CONCAT('plugin_enter:', plugin_enter), CONCAT('offers_view:', offers_view), ...) AS permissions
FROM users AS u
JOIN users_permissions AS up ON u.user_id = up.user_id
Then your PHP code can use explode() to split $row['permissions'] into array of name:value pairs, and then convert those to key=>value in the PHP array.
Another solution is to redesign your users_permissions table:
user_id permission_type value
1 plugin_enter 1
1 offers_view 0
...
2 plugin_enter 1
2 offers_view 1
...
Then you can query:
SELECT u.*, GROUP_CONCAT(permission_type, ':', value) AS permission
FROM users AS u
JOIN users_permissions AS up on u.user_id = up.user_id
Another possible sollution is to add prefixes to query.
Inspired by post: https://stackoverflow.com/a/9926134/2795923
SELECT `u`.*, ':prefix_start:', `uperms`.*, ':prefix_end:'
FROM (`users` as u)
LEFT JOIN `users_permissions` as uperms ON `u`.`user_id` = `uperms`.`user_id`
Output array looks like this:
[0] => array(
'user_id' => 1
'email' => xxx#xx.xx,
'prefix_start' =>
'plugin_enter' => 1,
'offers_view' => 0
'prefix_end' =>
)
...
Then easy PHP script to add all array data between prefix_start and prefix_end into own subarray.

How to return my query to multidimensional array using joins?

Is it possible to result any sql query into multidimensional array? In my case if I have a player with multiple teams.. how do I need to get a result like this
array(
'fname' => 'Mark',
'lname' => 'Caguioa',
'teams' => array(
'team' => 'Ginebra',
'team' => 'Hotshots'
)
)
And my idea in my query but it's not working...
$stmt = $this->sql->prepare("
SELECT
usr.fname,
usr.lname,
(
SELECT
team.name
FROM users usr
LEFT JOIN teams team
ON usr.gen_id = team.gen_id
) AS to 'teams'
FROM users usr
");
$stmt->execute(array(':gen_id' => 'generated_id'));
return $stmt->fetchAll(PDO::FETCH_ASSOC);
Any idea how to come up with this problem? Any help is very appreciated

Doctrine ResultSetMapping ignores entity

In doctrine, I want to fetch multiple entities from a native query. But I can't workout how to do it.
I have 3 entities: WBSOProject, Employee and WBSOBooking. Employees can log their work hours through a WBSOBooking entity which couples the Employee with a WBSOProject and it has an extra field for the logged hours.
To generate an overview of the worked hours per employee per project I've written the following code:
$query = "
select
project.id as project_id,
project.name,
employee.id as employee_id,
employee.bsn,
employee.name,
sec_to_time(sum(time_to_sec(wbsoBooking.total))) as balance
from wbso_projects project
inner join wbso_bookings as wbsoBooking on wbsoBooking.project_id = project.id
inner join employees as employee on employee.id = wbsoBooking.employee_id
group by project.year, project.name, employee.id, employee.name
";
$rsm = new ResultSetMapping();
$rsm
->addEntityResult("Kloktijden\\Model\\Entities\\WBSOProject", "project")
->addFieldResult("project", "project_id", "id")
->addFieldResult("project", "name", "name")
->addEntityResult("Kloktijden\\Model\\Entities\\Employee", "employee")
->addFieldResult("employee", "employee_id", "id")
->addFieldResult("employee", "bsn", "bsn")
->addFieldResult("employee", "name", "name")
->addScalarResult("balance", "balance");
$result = Model::getEntityManager()
->createNativeQuery($query, $rsm)
->getResult();
My desired result would be an array like this:
array(
[0] => array(
[0] => Kloktijden\\Model\\Entities\\WBSOProject,
[1] => Kloktijden\\Model\\Entities\\Employee,
"balance" => "00:00"
)
)
But somehow the Employee entity gets ignored, so my result looks like this:
array(
[0] => array(
[0] => Kloktijden\\Model\\Entities\\WBSOProject,
"balance" => "00:00"
)
)
So, my question is: why doesn't my resultset contain the Employee entity? And how can I fix this?

I have problems with arrays

So, I want to have table with users name, grades and subjects. Table will display only his grades. So I'm generating subject in foreach loop and reading grades depending on his id.
For subject I want to have an array which will contain infos about subject (teacher, classroom, etc.)
For now I have this array:
$subjects = array();
$getSubjects = mysqli_query($con, "SELECT * FROM predmeti");
while ($subject = mysqli_fetch_array($getSubjects)) {
$subjects[]= array(
$subject['subject_name'] => array(
'id' => $subject['id'],
'name' => $subject['name'],
'teacher' => $subject['teacher'],
'short_name' => $subject['short_name'],
'classroom' => $subject['classroom']
)
);
I know this isn't right. I can't get data for each subject.
Could you please help me?
You're accessing the columns by name while mysqli_fetch_array() returns only an integer indexed array. Have you tried mysqli_fetch_assoc()?

Categories