SQL select from three Tables and save in PHP array - php

I am working on a web application and would like to improve my code a little bit.
This is the SQL table structure I made for the application:
Now my question: Is there an easy way in PHP to select (with join or whatever?) the information from one specific event_id on all tables and save them in an array with followed structure for example:
$events = array(
'event_id' => 1,
'event_name' => '{"de":"Weltwirtschaftsforum","fr":"Forum \u00e9conomique mondial","it":"Forum Economico Mondiale"}',
'event_description' => '{"de":"Description DE","fr":"Description FR","it":"Description IT"}',
'event_lastedit' => 2011-12-01 10:23:35,
'locations' => array(
array(
'location_id' => 1,
'location_name' => 'Bern',
'location_date' => '01.01.2012',
'location_deadline' => 1323340607,
'timestamps' => array(
array(
'timestamp_id' => 1,
'timestamp_time' => '10:30',
'timestamp_seats' => 30
),
array(
'timestamp_id' => 2,
'timestamp_time' => '16:30',
'timestamp_seats' => 40
)
)
),
array(
'location_id' => 2,
'location_name' => 'Davos',
'location_date' => '02.02.2012',
'location_deadline' => 1323340607,
'timestamps' => array(
array(
'timestamp_id' => 3,
'timestamp_time' => '12:30',
'timestamp_seats' => 50
),
array(
'timestamp_id' => 4,
'timestamp_time' => '15:30',
'timestamp_seats' => 60
)
)
)
)
);
I hope the question is clear enough.
Greetings
Spinne
Edit:
What i did so far:
$event = $event_db->querySingle("SELECT * FROM rf_events WHERE event_id={$event_id}", true)
$rf_locations = $event_db->query("SELECT * FROM rf_locations WHERE event_id={$event_id}");
$locations = array();
$timestamps = array();
$counter = 0;
// Loop sql query result and save entries in $events array.
while ( $row = $rf_locations->fetchArray() ){
$locations[$counter] = array(
'location_id' => $row['location_id'],
'location_name' => json_decode($row['location_name'], true),
'location_date' => $row['location_date'],
'location_deadline' => $row['location_deadline']
);
$rf_timestamps = $event_db->query("SELECT * FROM rf_timestamps WHERE location_id={$row['location_id']}");
$counter2 = 0;
while ( $row2 = $rf_timestamps->fetchArray() ){
$locations[$counter]['timestamps'][$counter2] = array(
'timestamp_id' => $row2['timestamp_id'],
'timestamp_time' => $row2['timestamp_time'],
'timestamp_seats' => $row2['timestamp_seats']
);
$counter2++;
}
$counter++;
}

SELECT * FROM rf_events, rf_locations, rf_timestamps WHERE
rf_locations.event_id = rf_events.event_id AND
rf_timestamps.location_id = rf_locations.event_id
Then, use add the data into php accordingly.
You can refer to: MYSQL JOIN

Related

How to merge multiple dimension array cakephp

I just using function query() of cakePhp. The query will return array something like :
array(
(int) 0 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '11'
),
'cate_item' => array(
'price' => '150.000'
)
),
(int) 1 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
)
),
(int) 2 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
'rel_data_category' => '10'
),
'cate_item' => array(
'price' => '250.000'
)
)
)
Now, I want to check if array have the same cate.date will merge array (in this case is elements 0,1 of my array). Output something like :
array(
(int) 0 => array(
'cate' => array(
'date' => '2016-12-05',
),
'cate_detail' => array(
(int) 0 => array (
'rel_data_category' => '11',
'price' => '150.000'
),
(int) 1 => array(
'rel_data_category' => '10',
'price' => '250.000'
)
)
),
(int) 1 => array(
'cate' => array(
'date' => '2016-12-06',
),
'cate_detail' => array(
(int) 0 => array (
'rel_data_category' => '10'
'price' => '250.000'
)
)
)
)
Please help!
You will need to loop through the results and build a new array with the data in the form you want. You can use the CakePHP Hash::extract() method to map the dates to indexes so that you can combine the data for the dates.
For example:-
// Get out all the dates available and then flip the array so that we have a map of dates to indexes
$dates = Hash::extract($results, '{n}.cate.date');
$datesMap = array_flip($dates);
// Define an empty array that we will store the new merged data in
$data = [];
// Loop through the query results and write to the $data array using the map of dates
foreach ($results as $result) {
$key = $datesMap[$result['cate']['date']];
$data[$key]['cate'] = $result['cate'];
$data[$key]['cate_detail'][] = [
'rel_data_category' => $result['cate_detail']['rel_data_category'],
'price' => $result['cate_item']['price']
];
}

how to retrieve a table with many tables with PDO

Recently I've been using PDO
and I'd like to get a table with hasmany related table.
I can get a table with the tables like this
array (
0 =>
stdClass::__set_state(array(
'order_id' => '170',
'purchase_id' => '222',
'product_option_id' => '014',
)),
1 =>
stdClass::__set_state(array(
'order_id' => '170',
'purchase_id' => '600',
'product_option_id' => '015',
)),
)
with SQL query like this
SELECT ord.order_id,puc.purchase_id,puc.product_option_id
FROM order ord
JOIN purchase puc
ON ord.order_id = puc.order_id
WHERE ord.order_id = '170'
However I'd like to get this data like this
array (
0 =>
array(
'order_id' => '170',
'purchase_id' => '222',
'purchase' => array(
0 =>
array(
'purchase_id' => '222',
'product_option_id' => '014',
),
1 =>
array(
'purchase_id' => '600',
'product_option_id' => '015',
),
)
)
)
How do get the data like this with PDO?
Thank you
Luckily, you CAN have it with PDO.
Were you need anything but id from orders, the mission were impossible.
But as long as you need only unique value from orders, you can get the thing like this
array (
170 =>
array(
0 =>
array(
'purchase_id' => '222',
'product_option_id' => '014',
),
1 =>
array(
'purchase_id' => '600',
'product_option_id' => '015',
),
)
)
)
with as simple code as
$sql = "your sql";
$pdo->query($sql)->fetchAll(PDO::FETCH_GROUP);
However, I see very little sense in fetching the same order ID usedto filter the data. May be it should be some other query that is closer to your real needs? Like one that is fetching several orders?
You can't get it like this with PDO, but you can rearrange the results. A possible way to do it would be to use the array_reduce function.
$orders = array_reduce($results, function ($carry, $item) {
if (!isset($carry[$item->order_id])) {
$carry[$item->order_id] = array(
'order_id' => $item->order_id,
'purchase' => array(array(
'purchase_id' => $item->purchase_id,
'product_option_id' => $item->product_option_id,
));
);
} else {
$carry[$item->order_id]['purchase'][] = array(
'purchase_id' => $item->purchase_id,
'product_option_id' => $item->product_option_id,
);
}
return $carry;
}, array());

Query count and group by in cakephp 2.6.8

In cakephp 2.6.8, I am trying to query a table named "mytable" in order to count rows having common values.
So, this is my query :
$zone = $this->MyModel->find('all', array(
'fields' => array('zone_id', 'COUNT(zone_id) as count'),
'group' => 'zone_id'
));
Cakephp returns this result :
zone => array(
0 => array(
MyModel => array("zone_id" = 1) ),
0 => array("count" = 77)
),
1 => array(
MyModel => array("zone_id" = 2) ),
0 => array("count" = 55)
),
2 => array(
MyModel => array("zone_id" = 3) ),
0 => array("count" = 23)
)
);
All I need is something like this :
zone = array(
0 => array("zone_id" => 1, "count" => 77),
1 => array("zone_id" => 2, "count" => 55),
2 => array("zone_id" => 3, "count" => 23)
);
How could I do to get this working without creating any Virtual Field?
Thank you for your help !

conditions OR in join cakephp

I am a novice in cake and I'm having trouble with a query I want to do in a tables.
$options['joins'] = array(
array('table'=>'users_views',
'alias' => 'UserView',
'type' => 'inner',
'conditions' => array(
'View.id = UserView.view_id',
'UserView.user_id' => $user_id,
'UserView.like' => 1
),
)
);
$options['order'] = array('View.created' => 'desc');
$options['limit'] = 10;
That's my query so far, but what I need now add an OR condition. In this condition OR need to add
'UserView.user_id' => $user_id,
'UserView.like' => 0
I need the query returns the data that matches or are mine and the LIKE value is 0 if it is very difficult to understand please tell me.
Any help or advice will be well received.
Build the conditions like -
'conditions' => array(
0 => array('View.id = UserView.view_id'),
1 => array('UserView.user_id' => $user_id),
3 => 'UserView.like => 1 OR UserView.like => 0'
),
Or with using OR -
'conditions' => array(
0 => array('View.id = UserView.view_id'),
1 => array('UserView.user_id' => $user_id),
2 => 'UserView.like IN (0, 1)'
),
The following should work:
$options['joins'] = array(
array('table'=>'users_views',
'alias' => 'UserView',
'type' => 'inner',
'conditions' => array(
'View.id = UserView.view_id',
'OR' => array(
'UserView.user_id' => $user_id,
'UserView.like' => 1
)
),
)
);
$options['order'] = array('View.created' => 'desc');
$options['limit'] = 10;

Push array inside another array

I have a site develop in php and I have a function where I want to create an array inside other array.
My query are this (i'm using cakephp but in this case is only a problem of array don't tell me to use contain or something like that from cakephp because is a large query and I need to construct my query and my array in this mode)
My array $product_ingredient contain some value.
foreach ($product_ingredient as $key) {
$ingredient_level1 = $this->ProductIngredientVersion->query('SELECT * FROM ingredients_ingredients
WHERE ingredients_ingredients.ingredient_id = :ingredient_id
AND ingredients_ingredients.product_id = :id
AND ingredients_ingredients.version_id = :version_id
AND ingredients_ingredients.level = 1', array('id' => $id, 'ingredient_id' => $key['products_ingredients']['ingredient_id'], 'version_id' => $key['products_ingredients']['version_id']));
foreach($ingredient_level1 as $key2){
$ingredient_level2 = array($this->ProductIngredientVersion->query('SELECT * FROM ingredients_ingredients
WHERE ingredients_ingredients.ingredient_id = :ingredient_id
AND ingredients_ingredients.product_id = :id
AND ingredients_ingredients.version_id = :version_id
AND ingredients_ingredients.level = 2', array('id' => $id, 'ingredient_id' => $key2['ingredients_ingredients']['ingredient2_id'], 'version_id' => $key2['ingredients_ingredients']['version_id'])));
array_push($ingredient_level1, $ingredient_level2);
}
array_push($ingredient_ingredient, $ingredient_level1);
}
The result is that:
array(
(int) 0 => array(
(int) 0 => array(
'ingredients_ingredients' => array(
'id' => '34',
'level' => '1'
)
),
(int) 1 => array(
(int) 0 => array(
(int) 0 => array(
'ingredients_ingredients' => array(
'id' => '35',
'level' => '2'
)
)
)
)
)
But I would like this result
array(
(int) 0 => array(
(int) 0 => array(
'ingredients_ingredients' => array(
'id' => '34',
'level' => '1',
array(
'ingredients_ingredients' => array(
'id' => '35',
'level' => '2'
)
)
)
)
How can I solve?
Replace
array_push($ingredient_ingredient, $ingredient_level1);
by
array_push(
$ingredient_ingredient[0][0]['ingredients_ingredients'],
$ingredient_level1
);
This pushes the array to the appropriate cascade level. However it is very likely that this is the most efficient way, if you're unable to modify SQL or array structure elsewhere.

Categories