Grouping by date in php/mysql - php

I have a an array:
Array
(
[0] => Array
(
[id] => 53
[product] => something
[price] => £78
[quantity] => 23
[time] => 2011-07-15 20:29:21
)
[1] => Array
(
[id] => 52
[product] => product
[price] => £89
[quantity] => 1
[time] => 2011-07-14 00:51:57
)
[2] => Array
(
[id] => 51
[product] => product
[price] => £89
[quantity] => 1
[time] => 2011-07-14 00:51:37
))
I got this using the following sql statement:
select * from some_table GROUP BY time DESC
I want to display the results ordered by date, with the date as a heading:
e.g.
**2011-07-15**
all array elements for above date go here
**2011-07-15**
all array elements for above date go here
I thought about doing a seperate statement for each seperate day, but that sounds wrong. Is there a better way?

ORDER BY Time in your query, like this:
select * from some_table ORDER BY time DESC
Then loop in PHP:
$last_date = 0;
while($row = mysql_fetch_assoc($result)){
$date = date('Y-m-d', strtotime($row['time']));
if($date != $last_date)
echo '**'.$date.'**';
$last_date = $date;
echo '<br />';
echo 'Id: '.$row['Id'];
echo 'Product: '.$row['product'];
echo 'Price: '.$row['price'];
echo 'Quantity: '.$row['quantity'];
echo '<br /><br />';
}
If you're ouputting to a console instead of an HTML page then replace the '<br \>' with "\n"

<?
$arrDate = Array
(
[0] => Array
(
[id] => 53
[product] => something
[price] => £78
[quantity] => 23
[time] => 2011-07-15 20:29:21
);
$currentDate = null;
foreach ($arrDate as $item) {
if ($item["time"] == $currentDate) {
// print details
}
else {
$currentDate = $arrDate["time"];
// print date header.
// print details
}
}
?>

Related

PHP MySQL array_pad() on a multidimensional array to display values inside html table

I can't get this to work, I'm missing the last step...
1) query the database:
SELECT * FROM (
SELECT id_fattura, ROUND(valore_linea * quantita_linea, 2) AS quota, data_inizio, WEEK(data_inizio, 3) AS settimana, id_cliente, cod_servizio
FROM tbl_linee_fattura_el
) tbl_fe
LEFT JOIN (
SELECT id_cliente, CONCAT(cognome_cliente,' ', nome_cliente) AS nome
FROM tbl_clienti
) tbl_cl
ON tbl_fe.id_cliente = tbl_cl.id_cliente
WHERE cod_servizio = '01200'
AND data_inizio BETWEEN '2020-06-01' AND '2020-09-30'
GROUP BY settimana, nome
ORDER BY settimana, nome ASC
2) PHP code:
$stmt = $db->prepare($query);
$stmt->execute();
$all_result = $stmt->fetchAll();
//print_r($all_result);
$total_rows = $stmt->rowCount();
I get this:
Array
(
[0] => Array
(
[quota] => 65.00
[settimana] => 25
[nome] => John Wayne
)
[1] => Array
(
[quota] => 65.00
[settimana] => 25
[nome] => Clint Eastwood
)
[2] => Array
(
[quota] => 65.00
[settimana] => 25
[nome] => Charls Bronson
)
/*lot of other arrays, I left here only the relevant keys and values for the example.
*'quota' is a payment,
*'settimana' is week of the year (corresponding to date)
*'nome' is a customer */
)
the next step:
i found this function on stackoverflow (unfortunally I did not bookmark the page, i will update here If Icatch that page again)
<?php
function group_by($key, $data) {
$result = array();
foreach($data as $val) {
if(array_key_exists($key, $val)){
$result[$val[$key]][] = $val;
}else{
$result[""][] = $val;
}
}
return $result;
}
$all_result = group_by('nome', $all_result);
?>
and I get this:
Array
(
[John Wayne] => Array
(
[0] => Array
(
[settimana] => 25
[quota] => 10.00
)
[1] => Array
(
[settimana] => 26
[quota] => 21.00
)
)
[Clint Eastwood] => Array
(
[0] => Array
(
[settimana] => 26
[quota] => 22.00
)
[1] => Array
(
[settimana] => 27
[quota] => 23.00
)
[2] => Array
(
[settimana] => 28
[quota] => 24.00
)
)
[Charls Bronson] => Array
(
[0] => Array
(
[settimana] => 26
[quota] => 22.00
)
[1] => Array
(
[settimana] => 28
[quota] => 23.00
)
)
)
other step: build html table
<table>
<thead>
<tr>
<th>Nome</th>
<th>Week 25</th>
<th>Week 26</th>
<th>Week 27</th>
<th>Week 28</th>
</tr>
</thead>
<tbody>
<?php
$keys = array_keys($all_result);
for($i = 0; $i < count($keys); $i++) {
echo "<tr>";
echo "<td>".$keys[$i]."</td>";
$k = array(
'settimana' => '',
'quota' => ''
);
// need array_pad to avoid empty cells in the tables and php warnings
$all_pad = array_pad($all_result[$keys[$i]], 4, $k);
foreach($all_pad as $row) {
echo "<td>" . $row['quota'] . "</td>";
}
echo "</tr>";
}
?>
</tbody>
</table>
the final result:
As you can see results are displayed in the wrong columns:
John Wayne it's ok
Clint Eastwood values should be displayed in columns week 26, week 27 and week 28
Charles Bronson first value it's ok, second value shoul be in column week 28
(I put the right position inside the red baloons, W25, W26 and so on...).
How can I display the values at the right place?
A better MySQL query()?
A better array_pad() function?
A better foreach() loop?
UPDATE
I found this thread: Insert new item in array on any position in PHP
so, this is the code:
$keys = array_keys($all_result);
// this is the same function used to group by name, now group by weeks to get all the weeks numbers
$week = group_by('week', $all_result);
$weeks = array_keys($week);
for($i = 0; $i < count($keys); $i++) {
echo "<tr>";
echo "<td>".$keys[$i]."</td>";
foreach ($weeks as $k) {
if ( find_key_value($all_result[$keys[$i]], 'week', $k) !== true ) {
$pad = array(
'week' => $k,
'quota' => '',
);
// the code to insert arrays
array_splice( $all_result[$keys[$i]], $i - 1, 0, array($pad) );
// unfortunally (don't know why...) the first two arrays doesn't go in the right place, so I had to use this other code
array_multisort(array_column($all_result[$keys[$i]], 'week'), SORT_ASC, $all_result[$keys[$i]]);
}
}
foreach($all_result[$keys[$i]] as $row) {
echo "<td>" . $row['quota'] . "</td>";
}
echo "</tr>";
}
the final result:

PHP - Array does not turn into two-dimensional array

I need to make my array better.
I am getting data from database and i have milestones and milestone_parts. i want two-dimensional array. I need data of milestones in the first dimension and milestone_parts in the second dimension.
With this code:
$query = "
SELECT
a.id AS `milestone_id`,
a.titel AS `milestone_titel`,
a.client AS `client`,
a.verkocht_id AS `milestone_verkocht_id`,
b.id AS `milestonefase_id`,
b.titel AS `milestonefase_titel`,
b.milestone_id AS `milestonefase_milestone_id`,
b.omschrijving AS `milestonefase_omschrijving`
FROM `milestones` a
INNER JOIN `milestone_parts` b ON a.id=b.milestone_id
WHERE a.verkocht_id = '99'
";
$result= $db->query($dbh, $query);
while ($row = $db->fetchassoc($result))
{
$stone = array($row['milestone_verkocht_id'], $row['milestone_id'], $row['milestone_titel'], $row['client']);
$fase = array($row['milestonefase_milestone_id'],$row['milestonefase_id'],$row['milestonefase_titel']);
$stone[] = $fase;
echo '<pre>'; print_r($stone); echo '</pre>';
}
I get this as result
Array
(
[0] => 99
[1] => 6
[2] => string
[3] => string
[4] => Array
(
[0] => 6
[1] => 10
[2] => string
)
)
Array
(
[0] => 99
[1] => 6
[2] => string
[3] => string
[4] => Array
(
[0] => 6
[1] => 11
[2] => string
)
)
but I need (with names) this:
Array
(
[milestone_verkocht_id] => 99 // This is project id
[milestone_id] => 6
[milestone_title] => string
[client] => string
[10] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 10
[milestone_title] => string
)
[11] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 11
[milestone_title] => string
)
[12] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 12
[milestone_title] => string
)
)
Can you help me or do you have a solution? Help me please!
you can cycle each field returned by the query, checking the field name and making new arrays
$stones = array();
while ($row = $db->fetchassoc($result)) {
$fase = array();
$stone = array('milestones' => array());
foreach ($row as $k => $v) {
if (strpos($k, 'milestonefase_') === 0) {
$fase[$k] = $v;
} else {
$stone[$k] = $v;
}
}
if(!isset($stones[$stone['milestone_id']])) {
$stones[$stone['milestone_id']] = $stone;
}
$stones[$stone['milestone_id']]['milestones'][$fase['milestonefase_id']] = $fase;
}
echo '<pre>'.print_r($stones, true).'</pre>';
Edit
made some changes in order to match the request. Now we use $stones to store the information we already have on a milestone, adding to it the different "$fase" returned from the query
Probably a more clean way is to retrieve all the information with two different queries one for milestones and the other for the fases
Edit2
Added a sub-array for the milestone fases

Array group in php

I have the following array data:
[0] => stdClass Object
(
[schoolBin] => 110140014570
[schoolName] => школа-лицей № 66
[users] => 30
[tb0306_tb0301_id] => 514725
[tb0306_tb3002_id] => 17
[tb0306_countOfCorrectAnswers] => 14
[point] => 4
)
[1] => stdClass Object
(
[schoolBin] => 110140014570
[schoolName] => школа-лицей № 66
[users] => 30
[tb0306_tb0301_id] => 514725
[tb0306_tb3002_id] => 18
[tb0306_countOfCorrectAnswers] => 11
[point] => 4
)
So, i have many tb0306_tb0301_id from one schoolBin, and tb0306_tb0301_id has many tb0306_countOfCorrectAnswers of tb0306_tb3002_id. So i need to sum all tb0306_countOfCorrectAnswers of for all tb0306_tb0301_id of one schoolBin and i have many schoolBin, so i need to do the process for all schoolBin.
Tried the code:
$results = array();
foreach ($schoolResults as $schoolResult) {
$schoolBin = $schoolResult->schoolBin;
if (isset($results[$schoolBin])) {
$results[$schoolBin][] = $schoolResult;
} else {
$results[$schoolBin] = array($schoolResult);
}
}
But could not sum tb0306_countOfCorrectAnswers for one tb0306_tb0301_id.
Any helps guys!
here is the code to sum the tb0306_countOfCorrectAnswers for tb0306_tb0301_id of schoolBin. I use # to ingnore the worning for uninitial value.
$results = array();
foreach ($schoolResults as $schoolResult) {
#$result[$schoolResult->schoolBin][$schoolResult->tb0306_tb0301_id] += $schoolResult->tb0306_countOfCorrectAnswers
}

How to combine on this logic of my date

I have a bad time thinking... IDK what to do it's almost a day still can't figure it out... this is my display and I want to be like this...
http://i.imgur.com/lNhagUD.jpg
My Implementation
<?php
$userId = (int) (!isset($_GET['id'])) ? 1 : $_GET['id'];
$imagesResult = $db->getWhere("SELECT * FROM photo WHERE userID = {$userId} ORDER BY `when` DESC");
echo '<pre>';
print_r($imagesResult);
echo '</pre>';
foreach ($imagesResult as $key => $value) {
if(strtotime(date('j M Y', $value['when'])) == strtotime(date('j M Y'))) {
echo "<div class='item'><h3>Today</h3></div>";
} else {
echo "<div class='item'><h3>".date('j M Y', $value['when'])."</h3></div>";
}
echo "
<div class='item'>
<a href='photo.php?photoid={$value['id']}'><img src='img/picture/{$value['userId']}/{$value['imageLocation']}' height='180' /></a>
</div>";
}
?>
i don't know where to begin... that will return like that... it is hard to do when the date is outside the loop. i don't know where to put... please help me with this... just give me some little hints to do this...
Sample Return of $imageResult
Array
(
[0] => Array
(
[id] => 35
[userId] => 1
[albumId] =>
[imageLocation] => Background.png
[description] => some description
[tags] =>
[when] => 1394965560
)
[1] => Array
(
[id] => 36
[userId] => 1
[albumId] =>
[imageLocation] => Background1.png
[description] => some description
[tags] =>
[when] => 1394965560
)
)
First of all I suggest instead of echoing results directly, you should build a final array GROUPED BY dates (including today).
Like this:
$actualImageResults = array();
foreach ($imagesResult as $Image) {
$subarr = (date('j M Y', $Image['when']) == date('d M Y')) ? "today" : date("j-m-Y");
if(!is_array($actualImageResults[$subarr])) $actualImageResults[$subarr] = array();
array_push($actualImageResults[$subarr], $Image);
}
And then var_dump($actualImageResults) to see if data is properly grouped...
After this you can go ahead an echo results:
foreach($actualImageResults as $stamp => $images) {
echo "<strong>{$stamp}</strong>";
foreach($images as $image) {
echo $image["imageLocation"];
/.../
}
}
this is just a rough idea, you will need to make necessary adjustments according to your needs... but this is what I understand from your question and image link you posted. Its something like this -> making a final array from echoing having dates as its keys and all images grouped among them.
Issues:
I guess you are working in an environment with full error_reporting / debugging / etc... Turn off notices in error reporting on start of file. Something like:
<?php
error_reporting(E_ALL ^ E_NOTICE);
/.../
Try using a flag variable:
$userId = (int) (!isset($_GET['id'])) ? 1 : $_GET['id'];
$imagesResult = $db->getWhere("SELECT * FROM photo WHERE userID = {$userId} ORDER BY `when` DESC");
echo '<pre>';
print_r($imagesResult);
echo '</pre>';
$lastPrintedDateFlag = ""; // Flag variable
foreach ($imagesResult as $key => $value) {
if ($lastPrintedDateFlag != $value['when']) {
$lastPrintedDateFlag = $value['when'];
if(strtotime(date('j M Y', $value['when'])) == strtotime(date('j M Y'))) {
echo "<div class='item'><h3>Today</h3></div>";
} else {
echo "<div class='item'><h3>".date('j M Y', $value['when'])."</h3></div>";
}
}
echo "
<div class='item'>
<a href='photo.php?photoid={$value['id']}'><img src='img/picture/{$value['userId']}/{$value['imageLocation']}' height='180' /></a>
</div>";
}
But this is just a tricky way to archive what you want. I recommend to prepare a 2 dimensions array with images grouped by date, then you will print the result more clearly:
Example of the array:
Array
(
[16-03-14] => Array
(
[1] => Array
(
[id] => 35
[userId] => 1
[albumId] =>
[imageLocation] => Background.png
[description] => some description
[tags] =>
[when] => 1394965560
),
[2] => Array
(
[id] => 35
[userId] => 1
[albumId] =>
[imageLocation] => Background.png
[description] => some description
[tags] =>
[when] => 1394965560
)
)
[17-03-14] => Array
(
[1] => Array
(
[id] => 35
[userId] => 1
[albumId] =>
[imageLocation] => Background.png
[description] => fuck this Shit
[tags] =>
[when] => 1394965560
)
)
)

Using arrays with the Calendar class in CodeIgniter

I'm trying to create a rather complex array for my calendar application. It's supposed to contain dates, with the name of the day, the 'type' and the events, if any. I got as far as creating this:
[dates] {
[22] {
[day] => [Friday]
[type] => [weekday]
}
[23] {
[day] => [Saturday]
[type] => [Weekend]
}
[24] {
[day] => [Sunday]
[type] => [Weekend]
}
}
Now I would like to add another key called 'events'. I want to add the events for each day to the array.. So I could get something like:
[24] {
[day] => [Sunday]
[type] => [Weekend]
[events] {
[1] {
[title] => [test event]
[description] => [my event]
[date] => [24-04-2011]
}
[2] {
[title] => [test event 2]
[description] => [my second event]
[date] => [24-04-2011]
}
}
Not sure if this makes sense.
I created the first example using this code:
for($i = 1; $i <= $data['days_in_curr_month']; $i++)
{
$day_info = $this->get_day_info($i, $data['current_month'], $data['current_year']);
$dates[$i]['name'] = $day_info['day_name'];
$dates[$i]['type'] = $day_info['day_type'];
}
return $dates;
I then wanted to grab the event info by doing:
$event_info = $this->get_event_info($i, $data['current_month'], $data['current_year']);
in the same for loop.
My get_event_info method looks like this:
public function get_event_info($day, $month, $year)
{
$date = $year . "-" . $month . "-" . $day;
$this->db->where('date', $date);
$this->db->where('user_id', '1');
$query = $this->db->get('tblEvents');
$event_info = array();
foreach($query->result() as $row)
{
$event_info['events'][$row->id]['title'] = $row->title;
$event_info['events'][$row->id]['description'] = $row->description;
}
return $event_info;
}
It outputs arrays like this:
Array ( [events] => Array ( [1] => Array ( [title] => Project 2 [description] => Test: Project 2 ) [2] => Array ( [title] => Illustrator [description] => Test: Illustrator 2 ) ) )
Now, I return the $event_info from get_events_info to the create_dates_list method, but I'm not sure how I would go about adding my event arrays to the $dates array.
The get_event_info gets the events for each date (1 - end of month-). I then want to add those to my $dates array in the format listed above in my second example.
I'm confused cause these are rather complex arrays. Thanks in advance.
I think all you need to do is (for example):
$append_events = get_event_info($day, $month, $year);
$array['dates']['1']['event'] = $append_events['events'];
Then you can access your elements:
$array['dates']['1']['event'][$id]['title']
$array['dates']['1']['event'][$id]['description']

Categories